admin管理员组

文章数量:1397074

I've created a callable function from my Angular ponent. My angular ponent 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);
    });
  }

I've created a callable function from my Angular ponent. My angular ponent 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);
    });
  }
Share Improve this question edited Sep 14, 2023 at 5:32 Renaud Tarnec 83.2k10 gold badges98 silver badges129 bronze badges Recognized by Google Cloud Collective asked Apr 25, 2019 at 8:53 FSPFSP 1332 silver badges7 bronze badges 4
  • You should not call another Cloud Function from one Cloud Function. What is your exact User Requirement here? You want to create a record in the Realtime Database upon user creation? You could probably cover it in one Cloud Function. – Renaud Tarnec Commented Apr 25, 2019 at 8:57
  • Hey @RenaudTarnec - Essentially yes, but it's firestore in this instance. I have tried moving the return userRef.set method (from createUserRecord) into the .then(function(userRecord) of the createUser function. And that works. But it felt hacky. Would that actually be acceptable? Is there any particular reason not to chain functions in CF's? – FSP Commented Apr 25, 2019 at 9:17
  • @RenaudTarnec - I added an update to my code to explain the above ment. – FSP Commented Apr 25, 2019 at 9:35
  • I've just published an answer. Tell me how it works. – Renaud Tarnec Commented Apr 25, 2019 at 9:36
Add a ment  | 

1 Answer 1

Reset to default 3

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./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 remend 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!

本文标签: javascriptFirebase Cloud FunctionsHow to call another function and return objectStack Overflow