I'm playing around with firestore since I used realtime database in a course I did on angular. I created an angular app, and trying to get some documents based on a document property. However, I get this error each time:
ERROR FirebaseError: Missing or insufficient permissions.
Which is probably because i am doing something wrong and I don't understand enough about these type of requests. I finished up on maximilian's Angular course where working with realtime DB went like a breeze, but firestore is definitely proving to be more difficult.
Here is my code:
getTimesharesByOwnerId(): Observable<Timeshare[]> {
return this.currentUser$.pipe(
switchMap((user) => {
if (user) {
const ownerId = user.email;
const timesharesCollection = collection(this.afs, 'timeshares');
const q = query(
timesharesCollection,
where('ownerId', '==', ownerId)
);
return collectionData(q, { idField: 'id' }) as Observable<
Timeshare[]
>;
} else {
return of([]);
}
})
);
}
When the above request is done, the request does not include headers.
Now, I think:
a) I should add headers to my request with the currentUser$.token
b) I should find a way for firebase to check that header
But how should I do B to shield of certain actions? Because for some reason gemini and firebase always assumes I am using some kind of SDK for this? I'm using angular firestore, yes, but my header is never automatically attached. I store my logged in user in my Authservice as an observable.
The solution is probably very very easy, but I am currently feeling lost, as if I've wasted my time on this angular course because I'm too stupid to understand anything :/ I should probably use the SDK then? but am I not already? And does that mean I wasted an enormous amount of time setting up my auth service when firebase could've done this for me?
login(email: string, password: string): Observable<AuthResponseData> {
return this.http
.post<AuthResponseData>(
`https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=${firebaseConfig.apiKey}`,
{
email: email,
password: password,
returnSecureToken: true,
}
)
.pipe(
catchError(this.handleError),
tap((response) => {
this.handleAuthentication(
response.email,
response.localId,
response.idToken,
+response.expiresIn
);
})
);
}
And then in handleAuthentication I store the user like this: const user = new User(email, token, userId, expirationDate); this.user.set(user);
Turns out I was indeed using the SDK wrong. I was using a custom user object and custom methods to log in and then you manually need to provide the header indeed...
Next time just use the provided methods.