0

I've a small Angular application deployed to Firebase. There're only 2 users. The users are authenticated with their emails addresses. I'm able to get the user data in my Angular application.

In the development phase I've used the following Realtime Database rule:

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

Naturally, I'd like to make the full database only readable and writeable for that 2 users.

I've tried to set up the following rules:

{
  "rules": {
    ".read": "auth.uid !== null",
    ".write": "auth.uid !== null"
  }
}

As expected, I receive a 401 error.

My question would be, that how should I send the uid from within the Angular app endpoint requests?

I've tried sending it via path param, like:

this.http.get(`https://myappname.firebaseio.com/data.json?auth=${uid}`).toPromise(); 

But passing the logged in user's uid like this won't work. Should I send it with http headers? If yes, what should be the proper syntax?

Or do I need to send anything? Maybe I just need a better realtime database rule?


Edit:

I was able to retrieve the tokenId with the auth service's constructor.

this.firebaseAuth.authState.subscribe((user: any) => {
      if (user) {
        this.userData = user;
        localStorage.setItem('user', JSON.stringify(this.userData));
        JSON.parse(localStorage.getItem('user'));
        user.getIdToken().then((idToken: any) => {
          this.idToken = idToken;
        });
      } else {
        localStorage.setItem('user', null);
        JSON.parse(localStorage.getItem('user'));
      }
    });

Now when I call an API endpoint I just simply add the idToken as a path param, like this:

return this.http.get(`https://myapp.firebaseio.com/data.json?auth=${token}`).toPromise();

And Realtime Database rule looks like this:

{
  "rules": {
    ".read": "auth !== null",
    ".write": "auth !== null"
    }
}
Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
ergondar
  • 33
  • 6
  • One question: Why don't you use the JS SDK in your app? Any specific reason for using the RTDB REST API? – Renaud Tarnec Feb 13 '21 at 14:45
  • I've started building the Angular app based on an online course. Could elaborate a bit more? – ergondar Feb 13 '21 at 15:33
  • Normally, when you have a web app interacting with the Firebase services, you use the JS SDK, see https://firebase.google.com/docs/web/setup. It is way easier than using the REST APIs (actually the JS SDK is a layer above the REST APIs). – Renaud Tarnec Feb 13 '21 at 15:35
  • I'm using the AngularFireAuth package imported from `@angular/fire/auth`. In my service's constructor I'm getting the user data with the following [code](https://postimg.cc/SXbnbfBq). Isn't this the "best practice"? – ergondar Feb 13 '21 at 15:45
  • "Isn't this the "best practice"? This question is too broad to be answered here, unfortunately. It seems that you should get the token through your service. This is option 1 in my answer below. – Renaud Tarnec Feb 13 '21 at 15:52

1 Answers1

1

You interact between your Angular app and the Firebase Realtime Database with the Realtime Database REST API.

As explained in the doc, to send authenticated requests to the Realtime Database REST API through the auth query string parameter you need to generate and pass an ID token.

this.http.get(`https://myappname.firebaseio.com/data.json?auth=<ID_TOKEN>`).toPromise();

To generate this ID token, you can


Note that an ID token is totally different from a user uid.


PS: Since you are setting your rules with "auth.uid !== null", you may be interested by this SO answer.

Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121