0
votes

I have a Realtime Database within my Angular app and am using Firebase. I am trying to fetch data with a token attached as a param in my request as shown in the Firebase docs for RestAPI.

However, when I attach a token to the data, I receive back the 401 error "could not parse auth token".

I have tried this request inside and outside of my code only to get the same result.

The auth token is coming directly from the AngularFireAuth, which was created in my AuthService on signup:

activeUser = new BehaviorSubject<User>(null);
...
signup(email: string, password: string, name: string) {
  return this.firebaseAuth.auth
    .createUserWithEmailAndPassword(email, password)
    .then(res => {
      res.user.updateProfile({
        displayName: name
      });

      this.handleAuthentication(
        res.user.email,
        res.user.uid,
        res.user.displayName,
        res.user.refreshToken
      );
      return res;
    });
}

handleAuthentication(
  email: string,
  uid: string,
  displayName: string,
  token: string
) {
  const user = new User(email, uid, displayName, token);
  this.activeUser.next(user);
}
...

So I am creating a user with AngularFireAuth, and then using .next on the BehaviorSubject of activeUser in order to add the user with the email, uid, token, and display name. This token is then being used in the fetchWorkouts() function to get the data from the database.

My current code is:

fetchWorkouts() {
  return this.authService.activeUser.pipe(
    take(1),
    exhaustMap(activeUser => {
      return this.http.get<Workout[]>(
        "https://velo-coach-app.firebaseio.com/workouts.json?auth=" + activeUser.token
      );
    }),
   ...
}

I have also tried:

fetchWorkouts() {
  return this.authService.activeUser.pipe(
    take(1),
    exhaustMap(activeUser => {
      return this.http.get<Workout[]>(
        "https://velo-coach-app.firebaseio.com/workouts.json",
          {
            params: new HttpParams().set('auth', activeUser.token)
          }
        );
      );
    }),
   ...
}

I have also tried simply putting the entire token into the browser: https://myapp.firebase.io/workouts.json?auth=MYTOKEN. All of these result in the same problem: { "error" : "Could not parse auth token." }

When I send a Firebase request to get back some workouts with the request as such: https://myapp.firebase.io/workouts.json?auth=MYTOKEN, no matter how I send the request, it seems to always give back the same error.

My Realtime Database rules are as follows:

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

If I change these rules to:

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

and completely remove the token in my http request, then this works. It's only a matter of when those rules are turned on and I am attaching a token to the API request.

Is there something I am missing here? All the StackOverflow questions asking something similar to this are either unanswered, partially answered but not working, or use the deprecated Database Secrets.

1
The error message is suggesting that you're not actually passing a Firebase Auth User ID token. Please edit the question to show exactly how you're getting this value.Doug Stevenson
Added this code. The issue still persists even when I manually add the token to the request and submit it in the browserJeremy
You're going to have to be more specific. What exactly is the value you're passing? Is it what you expect? Please read: stackoverflow.com/help/minimal-reproducible-exampleDoug Stevenson
I was adding this while your comment appeared. Should have all the code there. I originally didn't include the code because I thought the fact I was attaching the token to the url directly and it still wasn't working, detached my code from the issue at hand and that it may be a firebase issueJeremy
Looks like the issue is the fact that I am using the refresh token...Jeremy

1 Answers

0
votes

You're passing the wrong value. res.user.refreshToken is not the ID token. Refresh tokens are a different thing used to get new ID tokens periodically.

You will have to call getIdToken() to asynchronously get that string value.