I have an "Uncaught FirebaseError: Missing or insufficient permissions." error when I sign into my app. The problem occurs on the redirection immediately after login. I currently have no error boundaries so a blank white screen with this error message appears in the web console.
I use the reactfire library.
Here some code:
My entry point: (index.tsx)
createRoute(document.getElementById('root')!).render(
<FirebaseAppProvider firebaseConfig={firebaseConfig}>
<SuspenseWithPerf fallback={"Loading..."} traceId={'web-initial-loading'}>
<Wrapper />
</SuspenseWithPerf>
</FirebaseAppProvider>
);
then the wrapper which just redirect to signin or dashboard depending on authentication:
export const Wrapper = () => <AuthCheck fallback={<SignIn/>}><Dashboard/></AuthCheck>;
The important part of my signin page is the sign in button:
<Button onClick={async () => auth.signInWithEmailAndPassword(email, password)}>
Sign In
</Button>
When I click on the button, there is a small delay caused by the fetching of the user and validation of password, etc (I should put a loading there later, but that is not a problem currently). Then the page turns white with errors in the console.
The page causing the error is the dashboard page. Here the code causing the error:
const user = useUser<User>();
console.log('id', user.uid); // it is ok
const accountRef = useFirestore().collection('users').doc(user.uid);
const account = useFirestoreDocDataOnce<Account>(accountRef);
console.log('account', account); // it is also ok
const companyRef = useFirestore().collection('companies').doc(account.company);
const contractsCollectionRef = companyRef.collection('contracts');
const contracts = useFirestoreCollectionData<Contract>(contractsCollectionRef, { idField: 'id' });
console.log(contracts); // never shown
The important thing to note is that if I refresh the page, then the AuthCheck takes me directly to the dashboard and everything is working like expected.
Do you see what I should do to make it work when I sign in too?
It doesn't work with , useUser() and useAuth() from reactfire. It also doesn't auth() from firebase.
EDIT As a temporary patch, I can change the sign in button's onClick method to that:
() => auth.signInWithEmailAndPassword(email, password).then(() => window.location.reload())
It's fast enough and on refresh, everything works fine. But I think it would be best to work without the reload.
EDIT 2 The same problem persists using react-router lib
index.ts
<HashRouter>
<AuthCheck fallback={<SignIn/>}>
<Route path={'/dashboard'}>
<Dashboard/>
</Route>
</AuthCheck>
</HashRouter>
SignIn.ts button onClick:
onClick={() => auth.signInWithEmailAndPassword(email, password).then(() => history.push('/dashboard'))}
It appears to be a bug in reactfire. See https://github.com/FirebaseExtended/reactfire/discussions/228.
A possible workaround is mentioned there suggesting to call the following function immediately after signing out:
export const clearFirestoreCache = () => {
const map = globalThis['_reactFirePreloadedObservables'];
Array.from(map.keys()).forEach(
(key) => key.includes('firestore') && map.delete(key),
);
};