angularfirebasegoogle-cloud-firestoreangular18

How do I correctly authenticate with firebase for each request


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


Solution

  • 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.