0

My app uses firebase to authenticate users. I use the token provided in header for making request to the backend server. Initially, i stored the token in a variable and all my service files access this variable for the token to add it to header before making request.

This was not of much use as expiry of the token cannot be checked this way and eventually server returned error for the requests. Now, Iam trying to get token from firebase provided method but since this is a 'promise', the control flow doesn't wait for the response and as a result blank token is sent in the request.

//in a general service file
getData(): Observable<any> {
    let tokenOptions = this.authService.getTokenHeader();
    return this.http.get(this.endPoints.dataUrl, tokenOptions)
    .map(res => {
        this.data = res.json().data;
        return this.data;
    })
    .catch(( error: any ) => Observable.throw( error.json().error || 'Server error' ))
}

//in authService file 
getTokenHeader() {
    const token = this.getToken();
    console.log(token);
    let tokenHeader = new Headers({ 'Authorization': token });
    tokenHeader.append('Content-Type', 'application/json');
    let tokenOptions = new RequestOptions({ headers: tokenHeader });
    return tokenOptions;
}

getToken() {
    firebase.auth().currentUser.getIdToken(true)
    .then(token => return token);
}

I have tried various methods like trying to returning tokenheader within then response of firebase method but all show type errors. I have been trying to get this solved from past two days. Since, this is a general workflow i think somebody can help me with a standard solution.

2 Answers 2

4

You are not chaining your promises. Here is an example how to do so:

//in a general service file.
getData(): Observable<any> {
  return new Observable(observer => {
    this.authService.getTokenHeader()
      .then(tokenOptions => {
        return this.http.get(this.endPoints.dataUrl, tokenOptions)
            .map(res => {
              this.data = res.json().data;
              observer.next(this.data);
              observer.complete();
            })
      })
      .catch(( error: any ) => {
        observer.error(error);
        observer.complete();
      });
  });
}

//in authService file 
getTokenHeader() {
  return firebase.auth().currentUser.getIdToken()
    .then(token => {
      console.log(token);
      let tokenHeader = new Headers({
        'Authorization': token
      });
      tokenHeader.append('Content-Type', 'application/json');
      let tokenOptions = new RequestOptions({
        headers: tokenHeader
      });
      return tokenOptions;
    });
}

Sign up to request clarification or add additional context in comments.

3 Comments

using this way now getData() method Observable shows typescript error as "A function whose declared type is neither 'void' nor 'any' must return a value". That method needs to return the response of the request.
I didn't provide the entire code. I am just providing a sample on how to chain promises. Anyway, I edited. I am not familiar with angular 4 observables but I think this should work.
I may have not asked the complete question i wanted thinking the error was in token request method. Anyways, this solves most of the problem. Thank you.
0

Define your methods to return a Promise and use then to access the value like this:

 getTokenHeader() : Promise<any>
 {
   return new Promise((resolve,reject)=>
   {
     this.getToken()
         .then(token=>
           {
                console.log(token);
                let tokenHeader = new Headers({ 'Authorization': token });
                tokenHeader.append('Content-Type', 'application/json');
                let tokenOptions = new RequestOptions({ headers: tokenHeader });
                resolve(tokenOptions);
           })
          .catch(()=>{/*do some error handling here*/});

   });
 }

 getToken() : Promise<any>
 {
   return new Promise((resolve,reject)=>
   {
      firebase.auth().currentUser.getIdToken(true)
      .then(token => resolve(token))
      .catch(()=>reject());
   });
 }

Eventually use getTokenHeader as a Promise as well.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.