Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

219
Visualizações
How to make callable google cloud function idempotent

I have a google cloud function that sends notifications to a firebase topic. The function was working fine till suddenly, it start to send more than one notification 2 or 3 at the same time. After contacting the Firebase support team, they told may I should make the function Idempotent, but I don't know how, since it's a callable function. for more details, this is a reference question containing more detail about the case. below is the function's code.

const functions = require("firebase-functions");

// The Firebase Admin SDK to access Firestore.
const admin = require("firebase-admin");
const {getMessaging} = require("firebase-admin/messaging");
const serviceAccount = require("./serviceAccountKey.json");

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: "https://mylinktodatabase.firebaseio.com",
});

exports.callNotification = functions.https.onCall( (data) => {
  // Grab the text parameter.
  const indicator = data.indicator;
  const mTitle = data.title;
  const mBody = data.body;
  // topic to send to
  const topic = "mytopic";
  const options = {
    "priority": "high",
    "timeToLive": 3600,
  };
  let message;
  if (indicator != null ) {
    message = {
      data: {
        ind: indicator,
      },
    };
  } else {
    message = {
      data: {
        title: mTitle,
        body: mBody,
      },
    };
  }

  // Send a message to devices subscribed to the provided topic.
  return getMessaging().sendToTopic(topic, message, options)
      .then(() => {
        if (indicator != null ) {
          console.log("Successfully sent message");
          return {
            result: "Successfully sent message", status: 200};
        } else {
          console.log("Successfully sent custom");
          return {
            result: "Successfully sent custom", status: 200};
        }
      })
      .catch((error) => {
        if (indicator != null ) {
          console.log("Error sending message:", error);
          return {result: `Error sending message: ${error}`, status: 500};
        } else {
          console.log("Error sending custom:", error);
          return {result: `Error sending custom: ${error}`, status: 500};
        }
      });
});
about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

In this blog Cloud Functions pro tips: Building idempotent functions, shows how to do a function idempotent using two approaches:

Use your event IDs

One way to fix this is to use the event ID, a number that uniquely identifies an event that triggers a background function, and— this is important—remains unchanged across function retries for the same event. 4.png

To use an event ID to solve the duplicates problem, the first thing is to extract it from the event context that is accessed through function parameters. Then, we utilize the event ID as a document ID and write the document contents to Cloud Firestore. This way, a retried function execution doesn’t create a new document, just overrides the existing one with the same content. Similarly, some external APIs (e.g., Stripe) accept an idempotency key to prevent data or work duplication. If you depend on such an API, simply provide the event ID as your idempotency key.

A new lease on retries

While this approach eliminates the vast majority of duplicated calls on function retries, there’s a small chance that two retried executions running in parallel could execute the critical section more than once. To all but eliminate this problem, you can use a lease mechanism, which lets you exclusively execute the non-idempotent section of the function for a specific amount of time. In this example, the first execution attempt gets the lease, but the second attempt is rejected because the lease is still held by the first attempt. Finally, a third attempt after the first one fails re-takes the lease and successfully processes the event.

5.png

To apply this approach to your code, simply run a Cloud Firestore transaction before you send your email, checking to see if the event has been handled, but also storing the time until which the current execution attempt has exclusive rights to sending the email. Other concurrent execution attempts will be rejected until the lease expires, eliminating all duplicates for all intents and purposes.

Also, as stated in this other question:

Q: Is there a need to make these onCall functions idempotent or will they never perform retries?

A: Calls to onCall functions are not automatically retried. It's up to your application's client-side and server-side code, to agree on a retry strategy.

See also:

  • Retrying Event-Driven Functions - Best practices
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda