与我同在。我花了一个月的时间回答这个问题:我已经使用Firebase数据库和Firebase函数大约一年了。我已经开始使用它了……但是只有当我以STRING的形式发送消息时,才可以使用它。问题是现在我希望接收一个对象,但是我不确定如何在FireBaseMessage中执行此操作。
我以前的结构:
messages
T9Vh5cvUcbqC8IEZowBpJC3
ZWfn7876876ZGJeSNBbCpPmkm1
message
"messages": {
".read": true,
"$receiverUid": {
"$senderUid": {
"$message": {
".read": true,
".write": "auth.uid === $senderUid"
我对侦听器的功能是:
exports.sendMessage = functions.database.ref('/messages/{receiverUid}/{senderUid}/{message}')
这是有问题的...出于多种原因。即,如果旧消息是“ Hey”,然后同一个人再次写“ Hey” ...,则原始消息将被覆盖。
所以我的NEW结构更像这样:
messages
-LkVcYqJoEroWpkXZnqr
body: "genius grant"
createdat: 1563915599253
name: "hatemustdie"
receiverUid: "TW8289372984KJjkhdsjkhad"
senderUid: "yBNbs9823789KJkjahsdjkas"
写为:
mDatabase.child("messages").push().setValue(message);
...我只是不确定如何编写该函数。
我的意思是……真的……应该是这样的:
exports.sendMessage = functions.database.ref('/messages/{receiverUid}/{senderUid}/{msgID}/{msgOBJECT}')
...但是我只是不确定Firebase的功能如何读取这种新结构。
现在,我将像这样推送到数据库:
mDatabase.child("messages").child(guid).child(user_Id).push().setValue(msgObject).addOnSuccessListener(this, new OnSuccessListener<Void>() {
@Override
public void onSuccess(@NonNull Void T) {
Log.d("MessageActivity", "Message Sent");
基本上,我只想接收消息对象……包含其中的所有内容……当它从通知到达时……并能够轻松地解析正文,日期,用户ID等。
有人可以解释解决此问题的正确方法吗?
UPATE (按要求)是完整的云功能:
exports.sendMessage = functions.database.ref('/messages/{receiverUid}/{senderUid}/{msgId}/{message}')
.onWrite(async (change, context) => {
const message = context.params.message;
// const messageId = context.params.messageId;
const receiverUid = context.params.receiverUid;
const senderUid = context.params.senderUid;
// If un-follow we exit the function.
if (!change.after.val()) {
return console.log('Sender ', senderUid, 'receiver ', receiverUid, 'message ', message);
}
console.log('We have a new message: ', message, 'for: ', receiverUid);
// Get the list of device notification tokens.
const getDeviceTokensPromise = admin.database()
.ref(`/users/${receiverUid}/notificationTokens`).once('value');
// Get the follower profile.
const getSenderProfilePromise = admin.auth().getUser(senderUid);
// The snapshot to the user's tokens.
let tokensSnapshot;
// The array containing all the user's tokens.
let tokens;
const results = await Promise.all([getDeviceTokensPromise, getSenderProfilePromise]);
tokensSnapshot = results[0];
const sender = results[1];
// Check if there are any device tokens.
if (!tokensSnapshot.hasChildren()) {
return console.log('There are no notification tokens to send to.');
}
console.log('There are', tokensSnapshot.numChildren(), 'tokens to send notifications to.');
console.log('Fetched sender profile', sender);
// console.log('David you're looking for the following UID:', followerUid);
// Notification details.
const payload = {
notification: {
title: `${sender.displayName} sent you a message.`,
body: message,
tag: senderUid
},
// 'data': { 'fuid': followerUid }
data: {
type: 'message',
name: sender.displayName
}
};
console.log('David you are looking for the following message:', message);
// Listing all tokens as an array.
tokens = Object.keys(tokensSnapshot.val());
// Send notifications to all tokens.
const response = await admin.messaging().sendToDevice(tokens, payload);
// For each message check if there was an error.
const tokensToRemove = [];
response.results.forEach((result, index) => {
const error = result.error;
if (error) {
console.error('Failure sending notification to', tokens[index], error);
// Cleanup the tokens who are not registered anymore.
if (error.code === 'messaging/invalid-registration-token' ||
error.code === 'messaging/registration-token-not-registered') {
tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
}
}
});
return Promise.all(tokensToRemove);
});
答案 0 :(得分:2)
由于您现在将发送方和接收方的UID存储在消息中,因此需要更改您的Cloud Function的声明。
代替此:
exports.sendMessage = functions.database.ref('/messages/{receiverUid}/{senderUid}/{msgId}/{message}').onWrite(async (change, context) => {
您需要触发以下内容:
exports.sendMessage = functions.database.ref('/messages/{messageId}').onWrite(async (change, context) => {
因此,通过此更改,您的代码将在每条写入/messages
的消息上触发。
现在,您“只是”需要获取发送者和接收者的UID。而且,由于您不再可以从context
获取它们,因此您将从change
获取它们。具体来说,change.after
包含数据快照,该快照在写入完成后 中存在于数据库中。因此(只要您不删除数据),就可以通过以下方式获取UID:
const receiverUid = change.after.val().receiverUid;
const senderUid = change.after.val().senderUid;
当然,您还将从那里获得实际的消息:
const message = change.after.val().message;
以防万一,您需要消息ID(在数据库中写入该消息的-L...
密钥):
const messageId = change.after.val().messageId;
答案 1 :(得分:1)
您只需要在messageId上触发:
exports.sendMessage = functions.database.ref('/messages/{messageId}').onWrite((change, context) => {
const changedData = change.after.val(); // This will have the complete changed data
const message = change.after.val().message; // This will contain the message value
......
});
阐述弗兰克的答案:
您无法从const message = context.params.message;
之类的上下文中获取数据,因为这些参数在上下文中已不存在。