问题
I'm building an Ionic app using Firebase, and therefore AngularFire2. In Angularfire2 you can authenticate, but it's an observable and have to subscribe to get the user object. The problem is that I can't seem to set this.user = user
because it doesn't seem like .subscribe
is in the same scope.
Here's an example, I have a auth.ts
and an app.component.ts
. In my service, I authenticate,
auth.ts
export class AuthService {
// user: Observable<firebase.User>;
user: object = {
displayName: null,
email: null,
emailVerified: null,
photoUrl: null,
uid: null
};
constructor(private facebook: Facebook,
private googlePlus: GooglePlus,
private platform: Platform,
private afAuth: AngularFireAuth) {
// this.user = afAuth.authState;
afAuth.authState.subscribe((user: firebase.User) => {
if (!user) {
this.user = null;
return;
}
this.user = {
displayName: user.displayName,
email: user.email,
emailVerified: user.emailVerified,
photoUrl: user.photoURL,
uid: user.uid
}
});
}
and in my app.component.ts:
app.component.ts
export class MytApp {
rootPage: any = TabsPage;
signinPage = SigninPage;
@ViewChild('nav') nav: NavController;
userProfile: any = null;
constructor(private platform: Platform,
private menuCtrl: MenuController,
private statusBar: StatusBar,
private splashScreen: SplashScreen,
private authService: AuthService) {
// this.authService.user.subscribe((user: firebase.User) => {
// var user = authService.user;
// if (user) {
// this.userProfile = user;
// this.onLoad(TabsPage);
// } else {
// this.userProfile = null;
// this.onLoad(SigninPage);
// }
// });
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
statusBar.styleDefault();
splashScreen.hide();
var user = authService.user; /* HERE */
console.log(user);
if (user) {
this.userProfile = user;
this.onLoad(TabsPage);
} else {
this.userProfile = null;
this.onLoad(SigninPage);
}
});
}
}
As you can see, right after var user = authService.user;
I run console.log(user);
and what I get is:
console.log(user);
displayName: null,
email: null,
emailVerified: null,
photoUrl: null,
uid: null
I use the user object for targeting user data in Firebase, so it's necessary. The problem is that the user object isn't updated, it's like it's out of the "scope" of the afAuth.authState.subscribe((user: firebase.User) => {}
.
Any idea how I can not subscribe, and just simply get the user object, or maybe extract the data from the subscribe so that I can easily retrieve it (because it's a service) from other components? Please help!
回答1:
You can't do a subscribe()
in your service. What you want to do, is to return an Observable
, and let the components handle the Observables
themselves, and not in the service. Reason for this is because your API call is asynchronous and your components cannot wait for the resolve of the http calls.
What you can do is you can return an Observable by mapping your AngularFireAuth
to an object that you desire.
export class AuthService {
public user: Observable<any>; //this can be any type you wish
constructor(private facebook: Facebook,
private googlePlus: GooglePlus,
private platform: Platform,
private afAuth: AngularFireAuth) {
this.user =
afAuth.authState.map((user: firebase.User) => {
if (!user) {
return null;
}
else return {
displayName: user.displayName,
email: user.email,
emailVerified: user.emailVerified,
photoUrl: user.photoURL,
uid: user.uid
}
});
}
}
Now, you can subscribe to your AuthService.user
in any other component:
export class MytApp {
rootPage: any = TabsPage;
signinPage = SigninPage;
@ViewChild('nav') nav: NavController;
userProfile: any = null;
constructor(private platform: Platform,
private menuCtrl: MenuController,
private statusBar: StatusBar,
private splashScreen: SplashScreen,
private authService: AuthService) {
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
statusBar.styleDefault();
splashScreen.hide();
//subscribe to AuthService
authService.subscribe(user => {
console.log(user);
if (user) {
this.userProfile = user;
this.onLoad(TabsPage);
} else {
this.userProfile = null;
this.onLoad(SigninPage);
}
})
});
}
}
来源:https://stackoverflow.com/questions/46082722/angularfire-observables-subscribe-not-setting-class-variable-in-same-scope