【发布时间】:2020-10-24 10:03:37
【问题描述】:
我花了太多时间试图弄清楚 FCM 的工作原理,所以我正在寻找一些智慧。我正在尝试使用 Firebase 云消息传递 (FCM) 为我的应用添加推送通知。我阅读了文档,但我并不完全理解它是如何工作的。我的应用程序是用 Java 编写的,对于消息传递我想使用 javascript。在我的应用程序中,我有一个用户可以交流的聊天室。一旦他收到新消息,我想设置推送通知。为了到达聊天室,数据库中的路径:
groups (collection) -> <group name> (document) -> chatRooms (collection) -> <chat ID> (document) -> roomMessages (collection) -> <message ID> (document)
chatRooms 集合中的每个文档都包含以下字段:
-
name- 房间名称。 -
lastMeesage- 在聊天室中发送的最后一条消息(发送消息后更新)。 -
lastMessageTimestamp- 最后一条消息的时间戳。 -
users- 在聊天室中交谈的用户(路径)数组。
roomMessages 集合中的每个文档都包含以下字段:
-
message- 发送的消息。 -
userName- 用户名。 -
userPath- firebase 中用户文档的路径。 -
timestamp- 消息的时间戳。
我一直在关注这个tutorial 如何做到这一点。我写了以下代码:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const db = functions.firestore;
exports.onMessageSent = db.document(`groups/{groupName}/chatRooms/{chatId}/roomMessages/{messageId}`).onCreate((messageDoc, context) => {
const message = messageDoc.message;
const senderName = messageDoc.senderName;
const senderPath = messageDoc.senderPath;
const chatId = context.params.chatId;
const groupName = context.params.groupName;
const groupPath = 'groups/' + groupName;
return admin.firestore().doc(senderPath).get().then(senderDoc => {
var senderPhoto = null;
if (typeof senderDoc.data().image !== 'undefined') {
senderPhoto = senderDoc.data().image;
}
return admin.firestore().doc(`groups/${groupName}/chatRooms/${chatId}`).get().then(chatRoomDoc => {
return chatRoomDoc.data().users.forEach((userPath, index) => {
return admin.firestore().doc(userPath).get().then(receiverDoc => {
console.log('Creating a chat notification for: ', receiverDoc.data().full_name);
let tokens = receiverDoc.data().tokens;
const payload = {
data: {
display_status: "admin_broadcast",
notification_type: "CHAT",
title: "New message from " + senderName,
body: message,
group_path: groupPath,
sender_path: senderPath,
sender_photo_url: senderPhoto,
chat_id: chatId
}
};
console.log("Sending notification");
return admin.messaging().sendToDevice(tokens, payload);
});
});
});
});
});
然后我跑了(它不允许我在本地运行,因为 - function ignored because the firestore emulator does not exist or is not running.):
firebase deploy --only functions
在android中我实现了以下类:
public class MessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
Log.d(TAG, "onMessageReceived: started");
Log.d(TAG, "onMessageReceived: message is: " + remoteMessage.getData());
// code
}
@Override
public void onNewToken(@NonNull String token) {
Log.d(TAG, "Refreshed user token: " + token);
sendRegistrationToServer(token);
}
// code
}
但在 firebase 控制台的功能选项卡的日志部分中,我收到以下错误:
onMessageSent
Error: Value for argument "documentPath" is not a valid resource path. Path must be a non-empty string.
at Object.validateResourcePath (/srv/node_modules/@google-cloud/firestore/build/src/path.js:406:15)
at Firestore.doc (/srv/node_modules/@google-cloud/firestore/build/src/index.js:427:16)
at exports.onMessageSent.db.document.onCreate (/srv/index.js:19:30)
at cloudFunction (/srv/node_modules/firebase-functions/lib/cloud-functions.js:132:23)
at /worker/worker.js:825:24
at <anonymous>
at process._tickDomainCallback (internal/process/next_tick.js:229:7)
这是什么意思以及如何解决?
【问题讨论】:
-
好像这个issue之前已经被提出来了。此外,对于与 Firebase 产品和服务有关的问题或疑虑,我想将您转至 Firebase Support page。因为它们更适合为您的 Firebase 查询提供答案。
标签: javascript android firebase google-cloud-functions firebase-cloud-messaging