I have a very standard Angular 12 application where a user logs in with Firestore and can then perform CRUD operations over their own documents.
As soon as you login to the application it throws
core.mjs:6495 ERROR FirebaseError: Missing or insufficient permissions.
at index.esm2017.js:4327
at ns (index.esm2017.js:4325)
at to.onMessage (index.esm2017.js:11273)
at index.esm2017.js:11227
at index.esm2017.js:11250
at index.esm2017.js:15093
at index.esm2017.js:15126
at ZoneDelegate.invoke (zone.js:372)
at Object.onInvoke (core.mjs:25853)
at ZoneDelegate.invoke (zone.js:371)
and no documents are loaded. However if I just refresh the page the error goes away and the documents load as expected.
My auth service is very standard
@Injectable({
providedIn: "root"
})
export class AuthService {
constructor(private angularFireAuth: AngularFireAuth, private router: Router) {
}
public login() {
signInWithPopup(getAuth(), new GithubAuthProvider())
.then(() => {
this.router.navigate(["/"]);
})
.catch((error) => {
console.log(error);
});
}
}
I'm trying to load the Firestore
documents in a RepositoryService
@Injectable({
providedIn: "root"
})
export class RepositoryService {
repositories$: BehaviorSubject<Repository[]> = new BehaviorSubject<Repository[]>([]);
constructor(private angularFireAuth: AngularFireAuth, private firestore: AngularFirestore) {
this.angularFireAuth.authState.subscribe(authUser => {
if (authUser) {
this.firestore
.collection("user")
.doc(authUser.uid)
.collection<Repository>("repositories")
.valueChanges()
.subscribe(this.repositories$);
}
});
}
}
Is a different instants of AngularFireAuth
being used here or something?
What's interesting is if I sign out, then refresh the page and log back in things work as expected. However signing out and straight back in again causes the Missing or insufficient permissions
exception to be thrown.
I was able to solve the error by replacing the standard subscription with a switchMap
constructor(
private angularFireAuth: AngularFireAuth,
private firestore: AngularFirestore,
) {
this.angularFireAuth.authState
.pipe(
switchMap((authUser) =>
authUser
? this.firestore.collection('user').doc(authUser.uid).collection<Repository>('repositories').valueChanges()
: of([])
)
)
.subscribe(this.repositories$);
}
I think the root of the problem was with the firebase listener trying to fetch documents during/after the logout process which was causing it to error out.
This would explain why refreshing the page between login sessions solves.
Awkward.