0

I am using angularFireAuth for authentication and the firestore as the DB.

My use-case is pretty simple:

  1. register a new user with email and password using firebase JS SDK methods.

  2. On successful registration, save the user's info in the firestore database.

If I would simply use the promise, It works fine. However rest of the app, the code mostly uses observables and It simply feels unnatural to use promise in the middle since most of the APIs either consumeobservable or return observable.

So I started to convert these ()=> promise<void> types to observable<void> using the defer - Rxjs

Here is an example:

user.service.ts

  export const USER_COLLECTION = 'users';
  private userCollection: AngularFirestoreCollection;
  constructor(    private db: AngularFirestore  ) {
    this.userCollection = this.db.collection(USER_COLLECTION);  
}    

//save user in firestore db  

saveUser(user: User): Observable {    
  return defer(() =>        
   this.userCollection.doc(user.UID).set(classToPlain(user))    
  );  
}

The registeration method is like:

registerUser(value: { email: string, password: string }): Observable {       
    return from(firebase.auth().createUserWithEmailAndPassword(value.email,value.password))      
              .pipe(switchMap(user => this.db.saveUser(user)))  
}

the switchMap never calls the this.db.saveUser . As a result, the user never is saved to firestore

... and in a component, I subscribe to the registerUser method

 this.subs.sink = this.authService.registerUser(this.loginForm.value)      
.subscribe();

I am not sure what is going wrong, The switchMap operator should ideally unsubscribe the last observable(from..) and should subscribe to the DB.saveUser

Irshad
  • 1,016
  • 11
  • 30

1 Answers1

0

I tried using defer instead of from to get a Cold Observable and instead of using the then syntax for Promise, I used async - await.

return defer(async () => {
  const cred = await firebase.auth().createUserWithEmailAndPassword(value.email, value.password);
  return cred.user;
})
  .pipe(
    map(user => this.transformService.transformUser(user)),
    switchMap(user => this.saveUser(user))
  );

worked like a charm!

Irshad
  • 1,016
  • 11
  • 30