Firebase Authentication. request.auth is null when the page is refreshed
P粉693126115
P粉693126115 2024-02-25 21:55:56
0
2
462

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:

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:

setPersistence(sharedFirebaseAuth, browserLocalPersistence)
    .then(() => {
        signInWithEmailAndPassword(sharedFirebaseAuth, email, password)
            .then((userCredential) => {
            })
            .catch((error) => {
            });
})

My onAuthStateChanged code

onAuthStateChanged(sharedFirebaseAuth, (user) => {
  if(user){
    user.reload().then(()=>{
      requestDocs();
    });
  }
})

P粉693126115
P粉693126115

reply all(2)
P粉258788831

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

P粉854119263

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

New file AuthContext.tsx

import React from "react"
import { User } from "firebase/auth";

export const AuthContext = React.createContext(null)

New file AuthProvider.tsx

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 = ({ children }: AuthProviderProps) => {
  const [user, setUser] = useState(null);
  
  useEffect(() => {
    const unsubscribe = sharedFirebaseAuth.onAuthStateChanged((firebaseUser) => {
      setUser(firebaseUser);
    });
    return unsubscribe
  }, []);

  return (
    {children}
  );
};

Then I updated my index.tsx like this

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(
  
    
      
    
  
);

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

const user = useContext(AuthContext);

    useEffect(() => {
        if(user){
            requestDocs();
        }
    },[user]);

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

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template