Облачные функции для Firebase: не отправлять уведомления всем пользователям - PullRequest
0 голосов
/ 25 января 2020

Я создал приложение электронной коммерции Android с Firebase и приложением Flutter для обновления узлов Firebase.

Я хочу отправлять уведомления всем пользователям всякий раз, когда администратор обновляет обменный курс.

Ниже приведен код, который я написал для отправки уведомления об обновлении всем зарегистрированным токенам с помощью облачной функции, но он отправляет уведомление только в приложение 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")
        }
    });
});

Это изображение моей Структуры базы данных в реальном времени .

Ответы [ 2 ]

1 голос
/ 25 января 2020

Исходя из предоставленного предоставленного снимка экрана вашей базы данных, данные ниже /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);
    }
  });
0 голосов
/ 25 января 2020

Не уверен, но попробуйте заменить

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

на

databaseReference.child(token).setValue(new Tokens(token));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...