Не может получить отправленное тестовое уведомление на устройство по токену, если токен меняется, ios с swift - PullRequest
0 голосов
/ 30 октября 2019

Да, здесь уже есть много одинаковых, но разных решений, но ни одно из них мне не помогло. Логика Firebase переполнена всем, что кажется способным сделать, но все же информация о том, «как», устарела и мало применима в актуальном состоянии. Проблема, с которой я столкнулся, заключается в том, что я хочу получать тестовое уведомление, отправляемое из консоли Firebase на мой телефон каждый раз, а не только на токен первого установленного приложения. Как только я удаляю приложение на моем телефоне и запускаю новое приложение с новым токеном, тестовое уведомление не достигает моего телефона, даже если я использую новый токен при отправке его из консоли Firebase.

Этоэто то, что я пытался сделать ..

В консоли Firebase я добавил проект и назвал его Testing, без аналитики.

Открыл мой Xcode V11.1 и создалСовершенно новый проект приложения ios для единого представления и введите название продукта: «Тестирование» с моей командой и т. д. Выберите язык: «Swift» и Пользовательский интерфейс: «Раскадровка».

В целевом объекте проекта «Тестирование» подпапка «Signing & Capabilities». Я нажал знак «плюс» и добавил «Push-уведомления». На всякий случай я также добавил «Фоновые режимы» и отметил «Удаленные уведомления».

В моем проекте тестирования xcode я теперь добавилследующий код в мой файл AppDelegate.swift.

import Firebase
import UIKit
import CoreData

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        setupPushNotificationsHandling(application)
        return true
    }

    private func setupPushNotificationsHandling(_ application:     UIApplication) {
          FirebaseApp.configure()

          application.registerForRemoteNotifications()

          UNUserNotificationCenter.current().delegate = self
              UNUserNotificationCenter.current().requestAuthorization(options:     [.alert, .sound]) { (_, _) in }
      }

      func application(_ application: UIApplication,     didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
          // Receive notifications from the "all" topic
          subscribeToNotificationsTopic(topic: "all")

      }

      func subscribeToNotificationsTopic(topic: String) {
          // Retry until the notifications subscription is successful
          DispatchQueue.global().async {
              var subscribed = false
              while !subscribed {
                      let semaphore = DispatchSemaphore(value: 0)

                  InstanceID.instanceID().instanceID { (result, error) in
                      if let result = result {
                          // Device token can be used to send notifications exclusively to this device
                          print("Device token \(result.token)")

                          // Subscribe
                          /*Messaging.messaging().subscribe(toTopic: topic)*/

                          // Notify semaphore
                          subscribed = true
                          semaphore.signal()
                      }
                  }

                  // Set a 3 seconds timeout
                  let dispatchTime = DispatchTime.now() + DispatchTimeInterval.seconds(3)
              _ = semaphore.wait(timeout: dispatchTime)
              }
          }
      }
    // MARK: UISceneSession Lifecycle

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // Called when the user discards a scene session.
        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
    }

    // MARK: - Core Data stack

    lazy var persistentContainer: NSPersistentContainer = {
        /*
         The persistent container for the application. This implementation
         creates and returns a container, having loaded the store for the
         application to it. This property is optional since there are legitimate
         error conditions that could cause the creation of the store to fail.
        */
        let container = NSPersistentContainer(name: "Testing")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.

                /*
                 Typical reasons for an error here include:
                 * The parent directory does not exist, cannot be created, or disallows writing.
                 * The persistent store is not accessible, due to permissions or data protection when the device is locked.
                 * The device is out of space.
                 * The store could not be migrated to the current model version.
                 Check the error message to determine what the actual problem was.
                 */
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()

    // MARK: - Core Data Saving support

    func saveContext () {
        let context = persistentContainer.viewContext
        if context.hasChanges {
            do {
                try context.save()
            } catch {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nserror = error as NSError
                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
            }
        }
    }

}

Этот фрагмент кода не будет получать уведомления без уведомления или без вывода сообщений, но я неПока в этом есть. Теперь я просто хочу получить простое уведомление, автоматически обрабатываемое API-интерфейсом Firebase. И я также прокомментировал следующую строку:

/*Messaging.messaging().subscribe(toTopic: topic)*/

Поскольку я еще не использую часть подписки.

Вернулся к моему проекту тестирования Firebase и добавил приложение ios. ввел идентификатор комплекта IOS, взятый из проекта xcode, и нажал «Зарегистрировать приложение».

Загрузил GoogleService-Info.plist и установил его в папку моего проекта тестирования xcode.

Открыл окно терминалана моем Mac и пошел в папку приложения «Тестирование» xcode и набрал ..

pod init

Открыл вновь созданный файл Pod и добавил модули, похожие на это.

target 'Testing' do
use_frameworks!
pod 'Firebase/Messaging'
end

Сохраненыизменяет и набирает команду в окне терминала.

pod install

Открывает вновь созданный файл рабочей области xcode с помощью команды pod, которая открыла проект XCode Testing.

Запустил код и принял командуУведомление подсказка. Он выписал токен устройства, я распечатал токен, но также получил следующее предупреждение:

[Firebase / Messaging] [I-FCM001000] Прокси-сервер удаленных уведомлений FIRMessaging включен, будет перебивать обработчики получателей удаленных уведомлений. Если вы предпочитаете вручную интегрировать обмен сообщениями Firebase, добавьте «FirebaseAppDelegateProxyEnabled» в ваш Info.plist и установите для него значение NO.

Поэтому я добавил «FirebaseAppDelegateProxyEnabled» с «NO», так как он тосковал поесть в файле info.plist.

Затем я очистил папку сборки и запустил ее снова .. на этот раз без предупреждения Swizzle, а только с токеном устройства, записанным в журнале.

СкопировалТокен и перешел на консоль Firebase, сделал отправку уведомления о тесте и добавил токен, записал некоторые глупые данные в заголовке и тексте и нажал «Тест». Ничего не произошло, не было автоматического уведомления в моем телефоне!?

Так что я подошел к консоли разработчика Apple и заметил в разделе «идентификаторы», что одна для тестирования уже создана, по крайней мере, не мной, по крайней мере, напрямую.

Здесь я начинаю чувствовать головокружение и не знаю, что делать ..

Мое головокружение заставило меня плыть по течению и добавило ключ в поле «Ключи» вКонсоль разработчика Apple. Назвал его «Firebase Testing Dev», проверил «Службу push-уведомлений Apple (APNs)» и зарегистрировал ее, нажав кнопку.

Загрузил ключ на мой Mac.

Вернулся к проекту «Тестирование» в Firebase под настройками «Cloud Messaging» и загрузил ключ под «ключом аутентификации APNs» приложения ios. Там я добавил Key ID и Team Id, полученные из консоли разработчика Apple.

Я бежал, как счастливый конь, к своему проекту XCode «Тестирование» и перестроил его, очистив папку сборки. и нажал знак воспроизведения. И я получил тот же токен, что и предыдущий, потому что я не удалял приложение из телефона между сборками.

Я взял токен и снова попробовал уведомление о тестовой отправке в консоли Firebase. Ничего не произошло, заметил, что мое приложение было на переднем плане и поместил его на задний план ... потом я получил свое первое счастливое счастливое уведомление, которое я отправил с консоли Firebase!

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

Перешел на консоль Firebase и проверил, чтобы отправить новое тестовое уведомление сновый токен, и ничего не случилось! Что-то не так.

Почему оно ломается, потому что я удаляю приложение с телефона только для того, чтобы снова установить то же самое приложение в комплекте и получить новый токен.

Что не так? Что я делаю не так?

Кстати, да, я запускал его на реальном устройстве.

...