请耐心等待。我花了一个月的时间来解决这个问题:我已经使用 Firebase 数据库和 Firebase 函数大约一年了。我已经让它工作了……但前提是我将消息文本作为字符串发送。问题是现在我希望收到一个 OBJECT,但我不确定如何在 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}')
这是有问题的...出于各种原因。也就是说,如果旧消息是“嘿”,然后同一个人又写了“嘿”……那么原始消息就会被覆盖。
所以我的新结构更像这样:
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");
基本上我只想接收消息对象......其中包含所有内容......当它从通知到达时......并且能够轻松解析正文,日期,用户标识等。
有人可以解释一下正确的方法吗?
更新 根据要求,这里是完整的云功能:
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);
});
最佳答案
由于您现在将发送者和接收者的 UID 存储在消息中,因此您的 Cloud Functions 函数的声明将需要更改。
取而代之的是:
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;
关于android - Firebase 函数接收对象而不是字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57915970/