Исходя из предоставленного предоставленного снимка экрана вашей базы данных, данные ниже /fcm-token
в вашей базе данных имеют два разных формата.
Когда вы добавляли данные вручную, вы использовали формат:
{
"fcm-token": {
"someRegistrationToken": {
"token": "someRegistrationToken"
},
"someOtherRegistrationToken": {
"token": "someOtherRegistrationToken"
}
...
},
...
}
Принимая во внимание, что из ваших «автоматически зарегистрированных» записей вы добавили токены с помощью:
{
"fcm-token": {
"somePushId": {
"fcmToken": "someRegistrationToken"
},
"someOtherPushId": {
"fcmToken": "someOtherRegistrationToken"
},
...
},
...
}
В своем коде облачных функций вы собрали все ключи, хранящиеся в /fcm-token
в массив, используя Object.keys(allToken.val())
, который даст вам массив, содержащий сочетание идентификаторов pu sh и токенов 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,
...
}
}
(Вы также можете использовать идентификатор пользователя владельца устройства вместо 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);
}
});