Emeric
Emeric

Reputation: 6895

Firebase cloud functions executed several times

I saw several topics about this problematic but sometimes it's juste due to few mistakes.

This is still a real problem for me and I did few experiences:

const addRoom = functions.region('europe-west1').https.onCall((data, context) => {
    console.log("a")
    return Promise.resolve();
});

enter image description here

Same result without the Promise.resolve():

const addRoom = functions.region('europe-west1').https.onCall((data, context) => {
    console.log("a")
});

enter image description here

(And of course I call the function just once on client side)

I created a web app and did few tests: 538 calls from cloud functions while it shouldn't exceed 100... I just can't believe this statistics, it's impossible. It's a serious issue.

What to do ?

Upvotes: 3

Views: 994

Answers (1)

cbrannen
cbrannen

Reputation: 61

How I've dealt with this is to create a collection in Firestore which logs the eventIds and then check this each time I use a cloud function I want to be idempotent.

//Check if exists in event log
async function isIdempotenceOk(eventId) {
    console.log(eventId);
    let eventDoc = await 
admin.firestore().collection('events').doc(eventId).get();
    if (eventDoc.exists) {
        console.log('Event already processed');
        return false;
    } else {
        await admin.firestore().collection('events').doc(eventId).set({ eventId: eventId });
        return true;
    }
}

Then you can call this in your other function like this:

const addRoom = functions.region('europe-west1').https.onCall((data, context) => {
console.log("a")

if(!await isIdempotenceOk(data.eventId)){return null;}
console.log('ok to continue')
return Promise.resolve();
});

This does mean you have a collection in Firestore which is called for each function which you perform this check on and there may be an alternative way for you to store the eventIds to check against.

Upvotes: 6

Related Questions