reactjs - Manglende tillatelser-feilmelding rett etter innlogging
Jeg har en "Uncaught FirebaseError: Missing or insufficient permissions." feil når jeg logger inn i appen min. Problemet oppstår ved omdirigeringen rett etter innlogging. Jeg har for øyeblikket ingen feilhåndteringsgrenser, så en tom hvit skjerm med denne feilmeldingen vises i nettleserkonsollen.
Jeg bruker reactfire-biblioteket.
Her er litt kode:
Mitt inngangspunkt: (index.tsx)
createRoute(document.getElementById('root')!).render(
<FirebaseAppProvider firebaseConfig={firebaseConfig}>
<SuspenseWithPerf fallback={"Loading..."} traceId={'web-initial-loading'}>
<Wrapper />
</SuspenseWithPerf>
</FirebaseAppProvider>
);
så wrapperen som bare videresender til innlogging eller dashbord avhengig av autentisering:
export const Wrapper = () => <AuthCheck fallback={<SignIn/>}><Dashboard/></AuthCheck>;
Den viktige delen av påloggingssiden min er påloggingsknappen:
<Button onClick={async () => auth.signInWithEmailAndPassword(email, password)}>
Sign In
</Button>
Når jeg klikker på knappen, er det en liten forsinkelse forårsaket av henting av brukeren og validering av passord, osv. (Jeg bør legge inn en lastemekanisme der senere, men det er ikke et problem for øyeblikket). Deretter blir siden hvit med feil i konsollen.
Siden som forårsaker feilen er dashbord-siden. Her er koden som forårsaker feilen:
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
Det viktige å merke seg er at hvis jeg oppdaterer siden, så tar AuthCheck meg direkte til dashbordet og alt fungerer som forventet.
Ser du hva jeg bør gjøre for å få det til å fungere når jeg logger inn også?
Det fungerer ikke med , useUser() og useAuth() fra reactfire. Det fungerer heller ikke med auth() fra firebase.
REDIGER Som en midlertidig løsning kan jeg endre onClick-metoden til logg-inn-knappen til dette:
() => auth.signInWithEmailAndPassword(email, password).then(() => window.location.reload())
Det er raskt nok, og ved oppdatering fungerer alt fint. Men jeg tror det ville være best å arbeide uten å måtte laste på nytt.
REDIGER 2 Det samme problemet vedvarer ved bruk av react-router-biblioteket
index.ts
<HashRouter>
<AuthCheck fallback={<SignIn/>}>
<Route path={'/dashboard'}>
<Dashboard/>
</Route>
</AuthCheck>
</HashRouter>
SignIn.ts knapp onClick:
onClick={() => auth.signInWithEmailAndPassword(email, password).then(() => history.push('/dashboard'))}
Svar #1
Det ser ut til å være en feil i reactfire. Se https://github.com/FirebaseExtended/reactfire/discussions/228.
En mulig løsning nevnes der som foreslår å kalle følgende funksjon umiddelbart etter utlogging:
export const clearFirestoreCache = () => {
const map = globalThis['_reactFirePreloadedObservables'];
Array.from(map.keys()).forEach(
(key) => key.includes('firestore') && map.delete(key),
);
};
Svar #2
Jeg fikset det endelig da jeg la til et rutingssystem (react-router-dom). index.ts
<ThemeProvider theme={AppTheme}>
<FirebaseAppProvider firebaseConfig={firebaseConfig}>
<SnackbarProvider maxSnack={6}>
<SuspenseWithPerf fallback={<Loader/>} traceId={'web-initial-loading'}>
<HashRouter>
<Route path={'/signIn'}>
<SignIn/>
</Route>
<Route path={'/dashboard'}>
<Dashboard/>
</Route>
</HashRouter>
</SuspenseWithPerf>
</SnackbarProvider>
</FirebaseAppProvider>
</ThemeProvider>
Og jeg la til en videresending til dashbordet ved pålogging og en videresending ved innlogging ved utlogging.
Jeg må finne en måte å håndtere automatisk utlogging hvis man ikke er logget inn mens man er på en beskyttet side. Men så vidt jeg forstår, kan vi ikke stole direkte på useAuth eller for mer kompleks ruting enn å vise en komponent. Hvis du gjør et kall som må autentiseres for å fungere, er det bedre å bruke et ekte rutingssystem.
REDIGER For å automatisk omdirigere til påloggingssiden og huske hvor du var, kan du erstatte
<Route path={'/dashboard'}>
<Dashboard/>
</Route>
med
{
user
? <> // All secured routes
<Route path={'/dashboard'}>
<Dashboard />
</Route>
</>
: <Redirect to={`/signIn redirectPath=${history.location.pathname}`} />
}
Hvor user er useUser()-hooken.
