简体   繁体   中英

Correct way to return a promise from firebase's onCall function?

According to the docs I've read, an onCall function should return a promise. Something like this:

...onCall((data, context) => {
    return db.collection('game').doc(game_id).delete();
});
...

This simply takes the promise associated with the delete function and returns it to the caller.

However, if I want to take an additional step after delete, then there are multiple return paths and I'm not clear on what to return:

...onCall((data, context) => {
    return db.collection('game').doc(game_id).delete()
        .then(){
            return db.collection('user').doc(user_id).delete()
        }
        //.catch(){ return ??? }
});
...

I've seen code similar to what I've typed above, but it isn't clear to me that this is correct. First, is it saying that by returning the game deletion promise, if there is an error, it will be returned to the user and if it is successful, then the user deletion promise will be returned to the user? What if there is a user deletion exception?

Do I have to create my own Promise object and call resolve or reject myself?

It's fine the way it is. You almost never need to create a new Promise. That's for cases where you call a function that doesn't return a promise, and provides a callback instead.

There are a lot of resources out there on learning to deal with promises. It doesn't really matter if the code is running in Cloud Functions or not - JavaScript promises work the same in any context. A callable function just needs that promise to know when the work is complete, and what to return to the caller.

 ...onCall((data, context) => { return db.collection('game').doc(game_id).delete().then(){ return db.collection('user').doc(user_id).delete() } //.catch(){ return??? } });

I've seen code similar to what I've typed above, but it isn't clear to me that this is correct. First, is it saying that by returning the game deletion promise, if there is an error, it will be returned to the user and if it is successful, then the user deletion promise will be returned to the user? What if there is a user deletion exception?

What you have in this code is Promise chaining , with the then() method. Since a call to promise.then() returns a Promise, the first return does return a promise and therefore it is fine for the Callable Cloud Function.

However, to answer to the end of your question, you should note that:

  1. If there is an error in the game deletion, the CF will stop and neither the game nor the user will be deleted
  2. If there is an error in the user deletion, the CF will stop and the game will be deleted (successfully deleted before the error) but not the user.

If you want to be sure both are deleted in one atomic operation (both are deleted or none is deleted), you should use a batched write as follows:

...onCall((data, context) => {


       let batch = db.batch();

       const gRef = db.collection('game').doc(game_id);
       batch.delete(gRef);

       const uRef = db.collection('user').doc(user_id);
       batch.delete(uRef);

       return batch.commit()

});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM