Cloud Functions for Firebase onWrite timeout

2019-02-12 15:22发布

问题:

I return transaction promise which should wait for transaction to finish before stopping the function. The transaction executes fine, but the promise seems to never resolve.

I see in the Firebase console that this function always times out after 60s.

const functions = require('firebase-functions');
const admin = require("firebase-admin");
const db = admin.database();


export let countFollowers = functions.database.ref('followers/{followee}/{follower}').onWrite(event => {
    const followee = event.params.followee;
    let path = `posts/${followee}/cnt_foll`;
    const countRef = db.ref(path);
    let out = countRef.transaction(current => {
        if (event.data.exists() && !event.data.previous.exists()) {
            return (parseInt(current) || 0) + 1;
        } else if (!event.data.exists() && event.data.previous.exists()) {
            return (parseInt(current) || 0) - 1;
        }
    });

    return out;
});

EDIT:

I solve the problem with the following "hack", I create a promise myself, because whatever .transaction is returning is not working:

return new Promise(function(resolve, reject) {
    countRef.transaction(current => {
        if (event.data.exists() && !event.data.previous.exists()) {
            return (parseInt(current) || 0) + 1;
        } else if (!event.data.exists() && event.data.previous.exists()) {
            return (parseInt(current) || 0) - 1; 
        }
    }, () => resolve(null));
});

回答1:

There was a known issue with older versions of the firebase-admin SDK where Firebase Database references and snapshots couldn't be JSON serialized and thus couldn't be used in return values for Cloud Functions. This includes transaction return values since they also have snapshots.

Your hack works around the bug; you should also get the fix if you update your version of firebase-admin.