我用Firebase和Flutter应用创建了一个电子商务Android应用程序来更新Firebase节点。
我想在管理员更新汇率时向所有用户发送通知。
下面是我编写的使用Cloud Function将更新通知发送到所有注册令牌的代码,但是它仅将通知发送到Flutter应用程序,而不是两个应用程序。
我不知道我在做什么错。
这是我的功能代码:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.helloWorld=functions.database.ref('Rates').onUpdate(evt =>{
const payload={
notification:{
title:"Today's Rate",
body :"Click here to see today's gold rate",
badge: '1',
sound: 'default'
}
}
return admin.database().ref('fcm-token').once('value').then(allToken =>{
if(allToken.val()){
console.log('token available');
const token = Object.keys(allToken.val());
console.log(admin.messaging().sendToDevice(token, payload));
return admin.messaging().sendToDevice(token, payload);
}else{
console.log('No Token Available');
throw new Error("Profile doesn't exist")
}
});
});
这是我的Realtime Database Structure的图片。
答案 0 :(得分:1)
基于数据库的provided screenshot,数据库中/fcm-token
下的数据具有两种不同的格式。
手动添加数据时,使用的格式为:
{
"fcm-token": {
"someRegistrationToken": {
"token": "someRegistrationToken"
},
"someOtherRegistrationToken": {
"token": "someOtherRegistrationToken"
}
...
},
...
}
在“自动注册”条目中,您使用以下方式添加了令牌:
{
"fcm-token": {
"somePushId": {
"fcmToken": "someRegistrationToken"
},
"someOtherPushId": {
"fcmToken": "someOtherRegistrationToken"
},
...
},
...
}
在您的Cloud Functions代码中,您使用/fcm-token
将Object.keys(allToken.val())
下存储的所有键收集到一个数组中,这将为您提供一个包含推送ID和FCM令牌混合的数组,这不是您所需要的想要,这就是为什么某些设备缺少通知的原因。
因此,简而言之,请选择一种或另一种格式。
在现有的混合结构中,您可以使用以下内容,该内容将忽略用作密钥的内容,仅提取令牌:
return admin.database().ref('fcm-token').once('value').then(allTokensSnapshot => {
if (allTokensSnapshot.exists()) {
console.log('Tokens available');
const tokenArray = [];
allTokensSnapshot.forEach((tokenSnapshot) => {
let token = tokenSnapshot.hasChild('fcmToken')
? tokenSnapshot.child('fcmToken').val()
: tokenSnapshot.child('token').val();
tokenArray.push(token);
});
return admin.messaging().sendToDevice(tokenArray, payload);
} else {
console.log('No tokens available');
throw new Error('No tokens available');
}
});
我个人将其弄平,以便您可以按原样使用代码,但这需要更改将令牌添加到数据库的方式:
数据库结构:
{
"fcm-token": {
"someRegistrationToken": true,
"someOtherRegistrationToken": true,
...
}
}
(如果需要,您也可以使用设备所有者的用户ID代替true
)
客户代码:
FirebaseInstanceId.getInstance().getInstanceId()
.addOnSuccessListener(new OnSuccessListener<InstanceIdResult>() {
@Override
public void onSuccess(InstanceIdResult result) {
DatabaseReference allTokensRef = FirebaseDatabase.getInstance().getReference().child("fcm-token");
String token = result.getToken();
Log.e("Test", "FCM Registration Token: " + token);
SharedPreferences preferences = this.getSharedPreferences("com.jk.jkjwellers", MODE_PRIVATE);
if(!(preferences.getBoolean("FCMAdded", false))){
allTokensRef.child(token).setValue(true);
preferences.edit().putBoolean("FCMAdded",true).apply();
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.e("Test", "Failed to get FCM registration token", e);
}
});
答案 1 :(得分:0)
不确定,但是尝试更换
databaseReference.push().setValue(new Tokens(token));
使用
databaseReference.child(token).setValue(new Tokens(token));