I have a sign-up function submit() that calls a signup()function in my authentication service, which is basically AngularFirebase createUserWithEmailAndPassword(...) . When it has been completed, another function updateUserDocument from my data service is called. This function looks for the user document in Firebase Firestore. That document is created by a cloud function, functions.auth.user().onCreate(user.createProfile) and is triggered when an auth object is created.
Using a cloud function is a convenient way to set all the initial user properties. The cloud function also makes it simple for me to implement sign-up with providers such as Google and Facebook.
However, the problem is that the cloud function does not have time to complete before the updateUserDocument function gets called and this results in it not finding the document in Firestore.
QUESTION: What is a good way to wait for the cloud function to complete before running updateUserDocument. Can I emit some kind of event from the cloud function, and if so, how do I listen to it client-side?
Submit function (in /sign-up.ts)
submit() {
if (!this.signUpForm.valid) {
return;
}
const {displayName, email, password } = this.signUpForm.value;
this.auth.signUp(email, password).pipe(
switchMap(({ user: { uid } }) => this.dataService.updateUserDocument({ uid, email, displayName: displayName })),
this.toast.observe({
success: 'Congrats! You are all signed up',
loading: 'Signing up...',
error: ({ message }) => `${message}`
})
).subscribe(() => {
this.router.navigate(['/create-profile']);
this.openVerticallyCentered('Welcome!')
});
}
Cloud function (in functions/src/user/index.ts)
export const createProfile = async (userRecord: any) => {
const uid = userRecord.uid;
const email = userRecord.email;
const photoURL = userRecord.photoUrl || '';
const displayName = userRecord.displayName || '';
const firstName = userRecord.firstName || '';
const lastName = userRecord.lastName || '';
const country = userRecord.country || '';
const dateOfBirth = userRecord.dateOfBirth || '';
const address = userRecord.address || '';
const suburb = userRecord.suburb || '';
const state = userRecord.state || '';
const postCode = userRecord.postCode || '';
const homePhone = userRecord.homePhone || '';
const mobilePhone = userRecord.mobilePhone || '';
const memNum = userRecord.memNum || '';
const memDueDate = userRecord.memDueDate || '';
const timestamp = FieldValue.serverTimestamp();
const memType = userRecord.memType || '';
const memStatus = userRecord.memStatus || '';
const isAdmin = userRecord.isAdmin || false
//const newUserRef = db.doc(`users/${uid}`)
// Convert any date to timestamp for consistency
try {
return await db
.collection(`users`)
.doc(userRecord.uid)
.set({
uid: uid,
email: email,
photoURL: photoURL,
displayName: displayName,
firstName: firstName,
lastName: lastName,
country: country,
dateOfBirth: dateOfBirth,
address: address,
suburb: suburb,
state: state,
postCode: postCode,
homePhone: homePhone,
mobilePhone: mobilePhone,
memNum: memNum,
memType: memType,
memStatus: memStatus,
memDueDate: memDueDate,
lastLoginDate: timestamp,
joined: timestamp,
updated: timestamp,
isAdmin: isAdmin,
});
} catch (message) {
return console.error(message);
}
};
index file for exporting function to firebase function (/functions/user/index)
exports.authOnCreate = functions.auth.user().onCreate(user.createProfile);