Firebase: нет токенов для отправки - PullRequest
0 голосов
/ 15 февраля 2019

iOS-клиент - облачная функция Firebase.Всякий раз, когда в пожарном хранилище создается «предмет», я хочу отправить push-уведомление конкретному клиенту.

'use strict';

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();

    exports.newMessageNotify = functions.firestore.document('conversation/{uid}/all/{mid}')
    .onCreate((change, context) => {

      const userID = context.params.uid;

      console.log("New message created2 "+ userID);
      const getUserPromise = admin.auth().getUser(userID);


      const path = '/users/' + userID + '/notificationTokens';
      console.log("User path is " + path); 
      const getDeviceTokensPromise = admin.database()
          .ref(path).once('value');

        // The snapshot to the user's tokens.
      let tokensSnapshot;

      // The array containing all the user's tokens.
      let tokens;

      return Promise.all([getDeviceTokensPromise, getUserPromise]).then(results => {
            tokensSnapshot = results[0];
          const user = 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 user profile', user);

          // Notification details.
          const payload = {
            notification: {
              title: 'You have a new message!',
              body: 'Message body'
            }
          };

           // Listing all tokens as an array.
          tokens = Object.keys(tokensSnapshot.val());

          // Send notifications to all tokens.
          return admin.messaging().sendToDevice(tokens, payload);

      }).then((response) => {
          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);
      });
    });

Это моя облачная функция, которая следует официальному примеру документов в https://github.com/firebase/functions-samples/blob/master/fcm-notifications/functions/index.js. Примечаниечто я также использовал `s вместо 'изначально для пути

admin.database()
          .ref('/users/${userID}/notificationTokens`).once('value');

, но это ничего не меняет.Я не получаю «токенов уведомлений для отправки» каждый раз.

Настройка моего клиента iOS:

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        FirebaseApp.configure()

        Messaging.messaging().delegate = self
        self.showLogin()

        UNUserNotificationCenter.current().delegate = self

        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (success, error) in
            if let e = error{
                print("Error occurred \(e.localizedDescription)")
            }else{
                print("Success")
            }
        }
        UIApplication.shared.registerForRemoteNotifications()


        NotificationCenter.default.addObserver(self, selector: #selector(tokenRefreshNotification(_:)), name: NSNotification.Name.MessagingRegistrationTokenRefreshed, object: nil)

        return true
    }

    @objc func tokenRefreshNotification(_ notification: NSNotification){
        let _ = true
    }

    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
        print("didReceive reg token")
    }

    func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
        print("didReceiveRemoteMessage")
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        print("Did receive")
        completionHandler()
    }

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Auth.auth().setAPNSToken(deviceToken, type: .sandbox)
    }

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        print("willPresentNotification")
        completionHandler(UNNotificationPresentationOptions.alert)
    }

Теперь, есть ли способ отладить это?Кроме того, меня больше всего смущает то, что в облачной функции я пытаюсь получить токены уведомлений для конкретного пользователя, в то время как на клиенте для устройства устанавливается токен устройства.Как эти токены установлены для конкретного пользователя?Это делается автоматически после успешной аутентификации?Насколько я понимаю, это происходит автоматически через swizzling, но как мне отладить его тогда?Могу ли я проверить содержимое базы данных администратора?

Я отправил тестовое уведомление с помощью панели управления firebase и успешно получаю уведомление в своем клиентском приложении для iOS, что означает, что уведомления работают.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...