簡體   English   中英

如何使Firebase消息傳遞功能異步

[英]How to make a Firebase messaging function asynchronous

我有一個Firebase消息傳遞功能,但返回功能似乎在其余功能之前執行。 這是代碼(很抱歉,它很長):

exports.newMessageNotification = functions.firestore
  .document(`messages/{messageId}`) // wildcard for the msg id
  .onCreate(async (change, context) => {
    const db = admin.firestore();
    const messageId: string = context.params.messageId;
    const messageRef = db.collection('messages').doc(messageId);
    const tokens = [];

    // get the message
    const message: Message = await messageRef
      .get()
      .then(q => q.data() as Message);

    const recipients: any = await message.recipients;

    const user: User = await db
      .collection('users')
      .doc(message.senderId)
      .get()
      .then(q => {
        return q.data() as User;
      });

    // Notification content
    const payload = await {
      notification: {
        title: `${user.name}`,
        body: `${message.message}`,
      },
    };

    console.log(payload);

    // loop though each recipient, get their devices and push to tokens
    Object.keys(recipients).forEach(async recipient => {
      const devicesRef = db
        .collection('devices')
        .where('userId', '==', recipient);
      const devices = await devicesRef.get();

      devices.forEach(res => {
        const token: string = res.data().token;
        console.log(token);
        tokens.push(token);
      });
    });

    console.log(tokens); // logs empty
    return await sendToCloud(tokens, payload);
  });

我認為問題在於forEach不是異步的,因此在等待forEach完成之前要執行最后一行代碼?

啊。 我最近在某個地方遇到了這個問題。 至少從我的經驗forEach ,您是正確的: forEach似乎未遵循async指令。 我不得不使用for ... in ...語法來:

  1. 讓它服從async (從父范圍)
  2. 順序處理,因為當時訂單對我很重要

在您的情況下,可能看起來像for (const recipient in recipients) { ... }


顯然,這是由forEach在不等待響應的情況下在每個項目上調用回調引起的。 即使回調是異步的, forEach也不知道await每個循環的響應。

來源: https : //codeburst.io/javascript-async-await-with-foreach-b6ba62bbf404


來自上面鏈接的博客評論的解決方案:

await Promise.all(
  Object.keys(recipients).map(async recipient => {
    const devicesRef = db
      .collection('devices')
      .where('userId', '==', recipient);
    const devices = await devicesRef.get();

    devices.forEach(res => {
      const token: string = res.data().token;
      console.log(token);
      tokens.push(token);
    });
  });
)

請注意, forEach已被map替換,並且位於Promise.all(...)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM