Reputation: 133
I've created a callable function from my Angular component. My angular component calls the createUser
function and successfully returns the userRecord
value.
However, what I would like to do is call another cloud function called createUserRecord
. I'm not overly familiar with promises and what needs to be returned where in this particular scenario.
Below are my two cloud functions. How would I go about calling createUserRecord
upon the success of createUser
?
export const createUser = functions.https.onCall(async (data, context) => {
console.log('data = ', data);
return admin.auth().createUser({
email: data.email,
password: data.password,
}).then(function (userRecord) {
return userRecord
})
.catch(function (error) {
return error;
console.log('Error creating new user:', error);
});
});
export const createUserRecord = functions.auth.user().onCreate((user, context) => {
const userRef = db.doc(`users/${user.uid}`);
return userRef.set({
email: user.displayName,
createdAt: context.timestamp,
nickname: 'bubba',
})
});
Update
This is a version I produced where I merged the two functions together. This does produce the expected result of creating and account and then writing to firestore. However, it does feel a little 'off' due to the fact that it doesn't return a value to the client.
export const createUser = functions.https.onCall(async (data, context) => {
console.log('data = ', data);
return admin.auth().createUser({
email: data.email,
password: data.password,
}).then(function (userRecord) {
const userRef = db.doc(`users/${userRecord.uid}`);
return userRef.set({
email: data.email,
name: data.name,
})
})
.catch(function (error) {
return error;
console.log('Error creating new user:', error);
});
});
Angular Callable Function
The sanitizedMessage
console log will return undefined.
addUser() {
const createUser = firebase.functions().httpsCallable('createUser');
const uniquePassword = this.afs.createId();
createUser({
email: this.userForm.value.email,
password: uniquePassword,
name: this.userForm.value.name,
}).then((result) => {
// Read result of the Cloud Function.
var sanitizedMessage = result.data.text;
console.log('sanitizedMessage = ', sanitizedMessage);
}).catch((error) => {
var code = error.code;
var message = error.message;
var details = error.details;
console.log('error = ', error);
});
}
Upvotes: 6
Views: 9610
Reputation: 83103
If you want to create a record in Firestore upon user creation you can very well do that within a unique Cloud Function. The following code will do the trick, making the assumption that you want to write to the users
Firestore collection.
const FieldValue = require('firebase-admin').firestore.FieldValue;
...
export const createUser = functions.https.onCall((data, context) => {
console.log('data = ', data);
return admin
.auth()
.createUser({
email: data.email,
password: data.password
})
.then(userRecord => {
return admin.firestore().collection('users')
.doc(userRecord.uid)
.set({
email: userRecord.displayName,
createdAt: FieldValue.serverTimestamp(),
nickname: 'bubba'
});
})
.then(() => {
return {
result: 'Success'
};
})
.catch(error => {
//Look at the documentation for Callable Cloud Functions to adapt this part:
//https://firebase.google.com/docs/functions/callable?authuser=0
});
});
"Is there any particular reason not to chain functions in CF's?" ?
As explained in the documentation, "Cloud Functions can be associated with a specific trigger". You can "chain" Cloud Functions by creating the corresponding triggers, for example, creating a doc in Firestore in one CF (Callable Function for example), that would trigger another CF that respond to a Firestore trigger). Having said that, in most cases you can probably cover a lot of needs in a unique Cloud Function, by chaining promises, instead of chaining Cloud Functions.
Finally, I would not recommend to call an HTTP Cloud Function from within a Cloud Function because (IMHO) HTTP Cloud Functions are more designed to be called by an external consumer (I even don't know if this would work).
It would be interesting to have Firebasers opinion on that!
Upvotes: 3