Flutter Cloud Messaging:如何从应用程序发送通知(而不是从 Firebase 控制台)

Posted

技术标签:

【中文标题】Flutter Cloud Messaging:如何从应用程序发送通知(而不是从 Firebase 控制台)【英文标题】:Flutter Cloud Messaging: how to send notification from the app (not from firebase console) 【发布时间】:2020-08-25 08:05:36 【问题描述】:

是否可以从应用内发送通知,而不是从 Firebase 上的云功能发送通知? 原因是,我想做类似的事情:FCM Push Notifications for Flutter,他们有这个功能将被部署到firebase:

export const sendToTopic = functions.firestore
  .document('puppies/puppyId')
  .onCreate(async snapshot => 
    const puppy = snapshot.data();

    const payload: admin.messaging.MessagingPayload = 
      notification: 
        title: 'New Puppy!',
        body: `$puppy.name is ready for adoption`,
        icon: 'your-icon-url',
        click_action: 'FLUTTER_NOTIFICATION_CLICK' // required only for onResume or onLaunch callbacks
      
    ;

    return fcm.sendToTopic('puppies', payload);
  );

此方法在 firebase 云功能上按预期工作,但我需要路径

.document('puppies/puppyId')

根据用户所在的聊天室进行动态调整,因此每次发送新消息时他都会收到通知,因此“chatroom22”将是一个变量:

.document('chatroom22/roomId')

那么是否可以在应用程序代码中执行此操作,或者可以在已部署的函数中执行此操作?

回应道格·史蒂文森的回答

好的,这是有道理的,并且有效。但是,现在每个人都会收到通知。我只希望给定聊天室中的人收到通知。我已经尝试过这样的事情,其中​​用户设备令牌被保存给给定的聊天室,然后我想通知所有这些令牌:

const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp(functions.config().functions);

var newData;
exports.myTrigger = functions.firestore.document('messages/messageId/room/roomId/message/messageId2').onCreate(async (snapshot, context) => 
    //

    if (snapshot.empty) 
        console.log('No Devices');
        return;
    

    newData = snapshot.data();

    const deviceIdTokens = await admin
        .firestore()
        .collection('messages/messageId/room/roomId/tokens/tokenId')
        .get();

    var tokens = [];

    for (var token of deviceIdTokens.docs) 
        tokens.push(token.data().device_token);
    
    var payload = 
        notification: 
            title: `$newData.sender`,
            body: `$newData.message`,
            sound: 'default',
        ,
        data: 
            push_key: 'Push Key Value',
            key1: newData.message,
        ,
    ;

    try 
        const response = await admin.messaging().sendToDevice(tokens, payload);
        console.log('Notification sent successfully');
     catch (err) 
        console.log(err);
    
);

但它似乎不适用于通配符..我怎样才能获得每个聊天室的具体目的地?

【问题讨论】:

【参考方案1】:

您可以为路径中的集合使用通配符:

functions.firestore.document('collectionId/documentId')

但这会触发 all ***集合中的 all 文档,这可能不是您想要的。

事实上,对***集合使用变量名实际上并不是在 Firestore 中建模数据的首选方式。考虑改为为所有房间创建一个***集合,然后使用子集合来包含它们的消息。如果你这样做,那么你的功能就会变得更清楚地定义为:

functions.firestore.document('rooms/roomId/messages/messageId')

Cloud Fuctions 只允许像这样的完整路径段使用通配符。没有其他模式或正则表达式。

【讨论】:

感谢您的回答。我已经编辑了我的问题以适合您的答案,因为我还没有完全达到目标。希望你能回答:)

以上是关于Flutter Cloud Messaging:如何从应用程序发送通知(而不是从 Firebase 控制台)的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Firebase Cloud Messaging onMessage 被触发两次

Flutter Firebase Cloud Messaging 如何自动关闭/取消通知?

Flutter Firebase Cloud Messaging - 应用程序在后台时的通知

当应用程序处于后台时,Flutter Cloud Messaging 自定义通知声音不起作用

Flutter Cloud Messaging:如何从应用程序发送通知(而不是从 Firebase 控制台)

如何为 Google Cloud Messaging 实现服务器以发送推送通知 android studio