0

Hi everybody I have searching hours around and tried everything such like BehaviorSubject or ReplaySube or with Events but unsuccessfull ..

Problem

I have a Profile Page in which is a button loginFb() which calls my users.services. This Service calls data with FacebookAPI and send them to database.. NOW it would be cool to send back a "callback" to my component with user object :)

Because when I (click) on login, I see the new User in Firebase but my page is not "refreshed", I think it's because my async is too late.. ?

Here is my profile.ts (ProfilePage)

import { Users } from '../../services/users.service';

export class ProfilePage {
    user :any;
    isConnected :boolean = false;

  constructor(public navCtrl: NavController, 
              public usersService: Users, 
              public modalCtrl: ModalController) { }

  loginFB(){
    this.usersService.registerUserFb();
    this.usersService.getUserFacebook().subscribe((userObject) => {
       this.user = userObject;
      })
    }
}

And here my users.services.ts

  getUserFacebookId(){
   Facebook.getLoginStatus().then((response) => {
     alert("id in getUSERFACEBOOKID = " + JSON.stringify(response.authResponse.userID));
      return response.authResponse.userID;
    });
  }

  getUserFacebook(){
    return this.af.database.object('users/' + this.getUserFacebookId());
  }

registerUserFb(){
    Facebook.login(['email']).then((response) => {
      Facebook.getLoginStatus().then((response) => {
        if(response.status == 'connected'){
          this.checkIfUserExists(response.authResponse.userID);
         }

        });
      });
  }

checkIfUserExists(uid) {
    let user = this.af.database.object('users/' + uid, { preserveSnapshot: true });
    user.subscribe(snapshot => {
    if(!snapshot.exists()) {
      this.saveInDatabase(uid);
    }
    });
}

saveInDatabase(uid){
      Facebook.api('/' + uid + 
              '?fields=id, name, ...])
            .then((data) => {
                var newUser = {
                  //data saving
                };
                this.af.database.object('users/' + uid).set(newUser);
                this.showToast("User successfully registered");
    });
  }
Community
  • 1
  • 1
luiswill
  • 952
  • 1
  • 11
  • 21
  • I'm not an `Observable` expert but I think that the issue comes from the fact that the `registerUserFb` function is not yet done when you call `getUserFacebook`. I think that you call "registerUserFb", and before the promise is done, you call `getUserFacebook` so you get nothing (as the promise is not completed) and when it completes, you don't emit anything on your `observable`, therefore, your subscriber does not know that the user changed. I think you should have a reference to your `observable` in your service and call its `emit` function in the `if` checking if the user is connected. – ssougnez Mar 08 '17 at 10:21

2 Answers2

2

you are sending mutiple asynchronous requests you have to wait until registerUserFb resolves and then call getUserFacebook :

 //ProfilePage     
 loginFB(){
    this.usersService
        .registerUserFb()
        .then(()=>{
             this.usersService.getUserFacebook().subscribe((userObject) => {
                this.user = userObject;
             });
        });
 }


//users.services.ts
registerUserFb(){
    return new Promise(resolve => {
      Facebook.login(['email']).then((response) => {
         Facebook.getLoginStatus().then((response) => {

            if(response.status == 'connected'){
               this.checkIfUserExists(response.authResponse.userID);
               resolve();
            }

         });
      });
    });
}
El houcine bougarfaoui
  • 35,805
  • 9
  • 37
  • 37
  • Hey thank you very much for you help ! But I don't know why but it calls `getUserFacebookId()` first, that's really weird, I will try to put promises everywhere .. – luiswill Mar 09 '17 at 07:10
  • Alright I tried some little things and it worked ! Thank you very much ! :) – luiswill Mar 09 '17 at 07:25
0

Here's some pseudocode for how it should look using RxJs:

registerUserFb():Observable<any>{
    return Facebook.login(['email']).flatMap(() => this.getLoginStatus());
}

getLoginStatus():Observable<any>{
    return Facebook.getLoginStatus();
}

loginFb(){
    this.registerUserFb().flatMap(()=>this.usersService.getUserFacebook()).subscribe((userObject=>{

    }))
}

As @ssougnez pointed out there is a race between two async calls.

Radu Cojocari
  • 1,759
  • 1
  • 22
  • 25