search

Home  >  Q&A  >  body text

Firebase Authentication. request.auth is null when the page is refreshed

When refreshing the page, client Firebase seems to think I have an authenticated user, but the firestore firebase rules imply that I don't have an authenticated user.

I have a Firebase app where users sign in with email and password via signInWithEmailAndPassword. I set persistence to browserLocalPersistence. Normally when a user logs in, the onAuthStateChanged method is called with the authenticated user object and the application runs normally. When the user refreshes the page, my onAuthStateChanged method fires again with a non-null user, but all Firebase queries fail due to my security rules. What am I doing wrong there.

This is a reactjs application. Please let me know if I can provide any other answers that might inspire you.

My firebase rules:

1

2

3

4

5

6

7

8

9

10

11

12

rules_version = '2';

service cloud.firestore {

  match /databases/{database}/documents {

    match /{document=**} {

      allow read, write: if isAuthenticated();

    }

    function isAuthenticated() {

        return request.auth != null && request.auth.uid != null;

    }

  }

   

}

My login code:

1

2

3

4

5

6

7

8

setPersistence(sharedFirebaseAuth, browserLocalPersistence)

    .then(() => {

        signInWithEmailAndPassword(sharedFirebaseAuth, email, password)

            .then((userCredential) => {

            })

            .catch((error) => {

            });

})

My onAuthStateChanged code

1

2

3

4

5

6

7

onAuthStateChanged(sharedFirebaseAuth, (user) => {

  if(user){

    user.reload().then(()=>{

      requestDocs();

    });

  }

})

P粉693126115P粉693126115384 days ago561

reply all(2)I'll reply

  • P粉258788831

    P粉2587888312024-02-26 20:51:07

    I think you forgot the comma between read and write, it should look like allow read, write: if isAuthenticated();

    reply
    0
  • P粉854119263

    P粉8541192632024-02-26 14:51:34

    I ended up having to implement an authentication provider so that it retained my user information.

    New file AuthContext.tsx

    1

    2

    3

    4

    import React from "react"

    import { User } from "firebase/auth";

     

    export const AuthContext = React.createContext<user |="" null="">(null)</user>

    New file AuthProvider.tsx

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    import { FC, useEffect, useState } from "react";

    import { User } from "firebase/auth";

    import { sharedFirebaseAuth } from "../Utils/SharedFirebase";

    import { AuthContext } from "./AuthContext";

     

    export interface AuthProviderProps {

        children: JSX.Element;

    }

     

    export const AuthProvider: FC<authproviderprops> = ({ children }: AuthProviderProps) => {

      const [user, setUser] = useState<user |="" null="">(null);

       

      useEffect(() => {

        const unsubscribe = sharedFirebaseAuth.onAuthStateChanged((firebaseUser) => {

          setUser(firebaseUser);

        });

        return unsubscribe

      }, []);

     

      return (

        <authcontext.provider value="{user}">{children}</authcontext.provider>

      );

    };</user></authproviderprops>

    Then I updated my index.tsx like this

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    import React from 'react';

    import ReactDOM from 'react-dom/client';

    import App from './App';

    import { AuthProvider } from './provider/AuthProvider';

    import "bootstrap/dist/css/bootstrap.min.css";

     

    const root = ReactDOM.createRoot(

      document.getElementById('root') as HTMLElement

    );

    root.render(

      <react.strictmode>

        <authprovider>

          <app>

        </app></authprovider>

      </react.strictmode>

    );

    Then update the part of app.tsx where I call onAuthStateChanged to the following

    1

    2

    3

    4

    5

    6

    7

    const user = useContext(AuthContext);

     

        useEffect(() => {

            if(user){

                requestDocs();

            }

        },[user]);

    After refreshing, it seems to retain all the necessary authentication information to extract the document.

    reply
    0
  • Cancelreply