Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js Firebase的云功能:不向所有用户发送通知_Node.js_Firebase_Firebase Realtime Database_Google Cloud Functions_Firebase Cloud Messaging - Fatal编程技术网

Node.js Firebase的云功能:不向所有用户发送通知

Node.js Firebase的云功能:不向所有用户发送通知,node.js,firebase,firebase-realtime-database,google-cloud-functions,firebase-cloud-messaging,Node.js,Firebase,Firebase Realtime Database,Google Cloud Functions,Firebase Cloud Messaging,我创建了一个带有Firebase的电子商务Android应用程序和一个用于更新Firebase节点的Flitter应用程序 我想在管理员更新汇率时向所有用户发送通知 下面是我编写的代码,它使用云函数向所有注册的令牌发送更新通知,但它只向Flutter应用程序而不是两个应用程序发送通知 我不知道我做错了什么 这是我的函数代码: 常量函数=需要“firebase-functions”; const admin=需要“firebase-admin”; admin.initializeAppfuncti

我创建了一个带有Firebase的电子商务Android应用程序和一个用于更新Firebase节点的Flitter应用程序

我想在管理员更新汇率时向所有用户发送通知

下面是我编写的代码,它使用云函数向所有注册的令牌发送更新通知,但它只向Flutter应用程序而不是两个应用程序发送通知

我不知道我做错了什么

这是我的函数代码:

常量函数=需要“firebase-functions”; const admin=需要“firebase-admin”; admin.initializeAppfunctions.config.firebase; exports.helloWorld=functions.database.ref'Rates'.onUpdate=>{ 常数有效载荷={ 通知:{ 标题:今天的汇率, 正文:点击这里查看今天的黄金汇率, 徽章:“1”, 声音:“默认” } } 返回admin.database.ref'fcm-token'。一次返回'value'。然后返回AllToken=>{ ifallToken.val{ console.log'tokenavailable'; const token=Object.keysallToken.val; console.logadmin.messaging.sendToDevicetoken,有效负载; 返回admin.messaging.sendToDevicetoken,有效负载; }否则{ console.log“没有可用的令牌”; 抛出新的ErrorProfile不存在 } }; };
这是我的图像。

不确定,但请尝试替换

databaseReference.push().setValue(new Tokens(token));

根据数据库的类型,数据库中/fcm令牌下面的数据有两种不同的格式

手动添加数据时,使用了以下格式:

{
  "fcm-token": {
    "someRegistrationToken": {
      "token": "someRegistrationToken"
    },
    "someOtherRegistrationToken": {
      "token": "someOtherRegistrationToken"
    }
    ...
  },
  ...
}
鉴于,从您的自动注册条目中,您使用以下方式添加了令牌:

{
  "fcm-token": {
    "somePushId": {
      "fcmToken": "someRegistrationToken"
    },
    "someOtherPushId": {
      "fcmToken": "someOtherRegistrationToken"
    },
    ...
  },
  ...
}
在云函数代码中,使用Object.keysallToken.val将/fcm token下存储的所有密钥收集到一个数组中,该数组将为您提供一个包含推送ID和fcm令牌的数组,这不是您想要的,也是某些设备缺少通知的原因

简而言之,决定一种格式还是另一种格式

临时工作场所 对于现有的混合结构,您可以使用以下选项忽略用作密钥的内容,只提取令牌:

返回admin.database.ref'fcm-token'。一次返回'value'。然后返回AllTokensSnapshot=>{ 如果allTokensSnapshot.exists存在{ console.log'Tokens available'; 常量标记数组=[]; allTokensSnapshot.forEachtokenSnapshot=>{ let token=tokenSnapshot.hasChild'fcmToken' ?tokenSnapshot.child'fcmToken'.val :tokenSnapshot.child'token'.val; tokenArray.pushtoken; }; 返回admin.messaging.sendToDevicetokenArray,有效负载; }否则{ 控制台。记录“无可用令牌”; 抛出新错误“无可用令牌”; } }; 数据库扁平化 就个人而言,我会将其展平,以便您可以按原样使用代码,但这需要更改向数据库添加令牌的方式:

数据库结构:

{ fcm令牌:{ someRegistrationToken:对, someOtherRegistrationToken:true, ... } } 如果需要,也可以使用设备所有者的用户ID而不是true

客户端代码:

FirebaseInstanceId.getInstance.getInstanceId .AddOnSuccessListener新建OnSuccessListener{ @凌驾 SuccessInstancedResult结果上的公共void{ DatabaseReference allTokensRef=FirebaseDatabase.getInstance.getReference.childfcm-token; 字符串标记=result.getToken; Log.eTest,FCM注册令牌:+Token; SharedPreferences preferences=this.getSharedPreferencescom.jk.jkjwellers,MODE_PRIVATE; if!preferences.getbooleanfcmaded,false{ allTokensRef.childtoken.setValuetrue; preferences.edit.putbooleanfcmaded,true.apply; } } } .AddOnFailureListener新建OnFailureListener{ @凌驾 公共空间onFailure@NonNull例外情况e{ Log.eTest,获取FCM注册令牌失败,e; } };
发送到Flatter应用程序的代码与发送到Android应用程序的代码没有区别。如果通知未到达,则很可能在捕获注册令牌的方式或处理来自FCM.DatabaseReference DatabaseReference=FirebaseDatabase.getInstance.getReference.childfcm-token的消息的方式上存在差异;字符串标记=FirebaseInstanceId.getInstance.getToken;Log.eTest,FCM注册令牌:+Token;如果this.getSharedPreferencescom.jk.jkjwellers,MODE_PRIVATE.getBooleanfcmaded,false{databaseReference.push.setValuenew-Tokenstoken;this.getSharedPreferencescom.jk.jkjwellers,MODE_PRIVATE.edit.putbooleanfcmaded,true.apply;}我正在用这些代码注册令牌。但是当我使用if条件时。令牌未在firebase上注册。当我删除它时。当用户打开应用程序时。它用相同的令牌一次又一次地注册自己。请不要在评论中发布附加信息,
但请编辑您的queston以包含它。注意-我刚刚尝试在firebase中手动输入令牌。当我将节点的名称与token相同,并在节点内部创建一个新的值名,该值与token和value相同。然后我收到通知。Linkclient代码为我提供了nullpointerException java.lang.RuntimeException:无法启动活动组件信息{com.jk.jkjwellers/com.jk.jkjwellers.ui.splashScreen.SplashScreenActivity}:java.lang.nullpointerException:无法在child@tusharkumar客户端代码是从您的问题中复制的。FirebaseInstanceIdgetToken显然已被弃用,因此我已使用现代方式更新了答案以获取令牌。更改客户端代码后。我以SOmetoken的形式获得了令牌:true,但当我从node.js获取令牌的值时。它给了我非空字符串的错误。因为它没有子fcmToken或令牌。?请同时提供解决方案触发器。对不起,出了问题。但这是我第一个使用node.js和firebase的程序。
{
  "fcm-token": {
    "somePushId": {
      "fcmToken": "someRegistrationToken"
    },
    "someOtherPushId": {
      "fcmToken": "someOtherRegistrationToken"
    },
    ...
  },
  ...
}