Да, здесь уже есть много одинаковых, но разных решений, но ни одно из них мне не помогло. Логика 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 и проверил, чтобы отправить новое тестовое уведомление сновый токен, и ничего не случилось! Что-то не так.
Почему оно ломается, потому что я удаляю приложение с телефона только для того, чтобы снова установить то же самое приложение в комплекте и получить новый токен.
Что не так? Что я делаю не так?
Кстати, да, я запускал его на реальном устройстве.