I'm trying to create my first app in Angular using AngularFire to help with Firebase operations and after logging in with Twitter I'm trying to add the user as a document in my users
collection.
Here's the full function:
processLoggedUser(): Promise<number> {
return this.afAuth.getRedirectResult().then(async result => {
if (result.user) {
const uid = result.user.uid;
const credential = result.credential as firebase.default.auth.OAuthCredential;
console.log('Twitter answer of AuthLogin: ', result)
this.uid = uid
let code = 0 // 0 = default code -> error
if (result.additionalUserInfo.isNewUser) {
console.log("New user")
this.user = {
uid: this.uid,
email: result.user.email,
displayName: result.user.displayName,
photoURL: result.user.photoURL.replace('_normal', ''),
miniPhotoURL: result.user.photoURL,
accessToken: credential.accessToken,
secret: credential.secret,
twitterId: result.additionalUserInfo.profile["id"],
username: result.additionalUserInfo.username,
bio: result.additionalUserInfo.profile["description"],
verified: result.additionalUserInfo.profile["verified"],
wallet: 0,
staff: false,
banned: false,
hidden: false
};
console.log(this.user)
await this.afs.collection('users').doc(this.uid).set(this.user || {nome: "oops"}).then(res => {
console.log("User created", res)
code = 2 // Number code for new user
}).catch(err => {
console.log("Error creating user", err)
code = 0 // Number code for error
})
return 2
} else {
await this.getUser(uid).then(res => res.subscribe(res => {
if (res == undefined) {
this.signOut()
code = 4 // Number code for user not found
} else {
this.user = res
console.log("Existing user", this.user)
code = 1 // Number code for existing user
}
}))
}
return code
}else {
return 3
}
}).catch((error) => {
console.warn(error)
return 0 // Number code for error
})
}
What really bothers me is this part:
await this.afs.collection('users').doc(this.uid).set(this.user).then(res => {
console.log("User created", res)
code = 2 // Number code for new user
}).catch(err => {
console.log("Error creating user", err)
code = 0 // Number code for error
})
It never gets to .then() or .catch(), it just gets stuck waiting forever for a response. But, if i put this exact same code, let's say, in the constructor or anywhere else, it works perfectly and actually creates the document in the Firestore Database.
Can anyone suggest me a way to make this work?
CodePudding user response:
Found one, https://github.com/angular/angularfire/issues/2585
So basically they are telling you need to subscribe to ".authState or .user from AngularFireAuth", (note, authState triggers only on login/logout) i'd try something like below but i have no way to test, so sorry if anything:
Also, added some note about your subscribe function below, you can convert them to promise in the way i did also.
import { first, tap } from "rxjs/operators";
processLoggedUser(): Promise<number> {
return this.afAuth
.getRedirectResult()
.then(async (result) => {
if (result.user) {
const authUser = await this.afAuth.user
.pipe(
// Logs
tap((user) => {
console.log("User changed: ", user);
}),
// to unsibscribe after first event emitted
first()
)
.toPromise(); // toPromise is tricky, a chance it will not fire for you, i have no way to test.
const uid = result.user.uid;
const credential = result.credential as firebase.default.auth.OAuthCredential;
console.log("Twitter answer of AuthLogin: ", result);
this.uid = uid;
let code = 0; // 0 = default code -> error
if (result.additionalUserInfo.isNewUser) {
console.log("New user");
this.user = {
uid: this.uid,
email: result.user.email,
displayName: result.user.displayName,
photoURL: result.user.photoURL.replace("_normal", ""),
miniPhotoURL: result.user.photoURL,
accessToken: credential.accessToken,
secret: credential.secret,
twitterId: result.additionalUserInfo.profile["id"],
username: result.additionalUserInfo.username,
bio: result.additionalUserInfo.profile["description"],
verified: result.additionalUserInfo.profile["verified"],
wallet: 0,
staff: false,
banned: false,
hidden: false
};
console.log(this.user);
await this.afs
.collection("users")
.doc(this.uid)
.set(this.user || { nome: "oops" })
.then((res) => {
console.log("User created", res);
code = 2; // Number code for new user
})
.catch((err) => {
console.log("Error creating user", err);
code = 0; // Number code for error
});
return 2;
} else {
await this.getUser(uid).then((res) =>
// Note: subscribe is not a promise, not awaitable, codes will not be set
res.subscribe((res) => {
if (res == undefined) {
this.signOut();
code = 4; // Number code for user not found
} else {
this.user = res;
console.log("Existing user", this.user);
code = 1; // Number code for existing user
}
})
);
}
return code;
} else {
return 3;
}
})
.catch((error) => {
console.warn(error);
return 0; // Number code for error
});
}