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

Tha*_*nos 5 flutter google-cloud-functions firebase-cloud-messaging google-cloud-firestore

是否可以从应用程序内发送通知而不是 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);
  });
Run Code Online (Sandbox Code Playgroud)

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

.document('puppies/{puppyId}')
Run Code Online (Sandbox Code Playgroud)

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

.document('chatroom22/{roomId}')
Run Code Online (Sandbox Code Playgroud)

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

回应道格史蒂文森的回答

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

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);
    }
});
Run Code Online (Sandbox Code Playgroud)

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

Dou*_*son 0

您可以在路径中对集合使用通配符:

functions.firestore.document('{collectionId}/{documentId}')
Run Code Online (Sandbox Code Playgroud)

但这将触发所有顶级集合中的所有文档,这可能不是您想要的。

事实上,对顶级集合使用变量名称实际上并不是在 Firestore 中对数据进行建模的首选方法。考虑为所有房间建立一个顶级集合,然后使用子集合来包含它们的消息。如果你这样做,那么你的功能将变得更加清晰地定义为:

functions.firestore.document('rooms/{roomId}/messages/{messageId}')
Run Code Online (Sandbox Code Playgroud)

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