How can I subscribe user to a topic for notifications as soon as app starts up?
Asked Answered
P

3

6

I am using HTTP POST to send notifications to all users on the app. To do this I have a topic to subscribe to called "global". I want every user to be automatically subscribed to this topic to make sure they get the notifications (assuming they have notifications turned on).

Where in my code should I put the subscription to make sure they will always be subscribed? My fear is that I put it somewhere wrong and they never end up being subscribed. I tried to subscribe at the end of didFinishLaunchingWithOptions but it looks like it is too early to do it here (I guess since user may not have accepted notification prompt yet?).

Currently the subscription is in didRegisterForRemoteNotificationsWithDeviceToken however this does not get called on the first app run so for it to work I have to run the app a second time... Here is my relevant code in AppDelegate:

import UIKit
import Firebase
import FirebaseMessaging
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, FIRMessagingDelegate {

var window: UIWindow?


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

    FIRApp.configure()

    if #available(iOS 10.0, *) {
        let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter.current().requestAuthorization(
            options: authOptions,
            completionHandler: {_, _ in })

        // For iOS 10 display notification (sent via APNS)
        UNUserNotificationCenter.current().delegate = self
        // For iOS 10 data message (sent via FCM)
        FIRMessaging.messaging().remoteMessageDelegate = self

    } else {
        let settings: UIUserNotificationSettings =
            UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
        application.registerUserNotificationSettings(settings)
    }

    application.registerForRemoteNotifications()

    return true
}



func applicationReceivedRemoteMessage(_ remoteMessage: FIRMessagingRemoteMessage) {
    print("applicationReceivedRemoteMessage")
}



func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    if let refreshedToken = FIRInstanceID.instanceID().token() {
        print("InstanceID token: \(refreshedToken)")
        FIRMessaging.messaging().subscribe(toTopic: "/topics/global")
    }
}



@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    completionHandler(UNNotificationPresentationOptions.alert)
}



func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
    // If you are receiving a notification message while your app is in the background,
    // this callback will not be fired till the user taps on the notification launching the application.
}



func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    // If you are receiving a notification message while your app is in the background,
    // this callback will not be fired till the user taps on the notification launching the application.
}
Pruinose answered 23/5, 2017 at 23:56 Comment(0)
M
10

You need to have the topic subscription in two places.

One just after FIRApp.configure(). Also update the Firebase iOS SDK version. Seems like you're having an older version.

According to new version (FirebaseMessaging 2.0.1).

if Messaging.messaging().fcmToken != nil {
    Messaging.messaging().subscribe(toTopic: “foo”)
}

Then the second one when token is refreshed.

func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
    Messaging.messaging().subscribe(toTopic: “foo”)
}

Here's the link to original answer. Check the answer contributor has provided.

https://github.com/firebase/quickstart-ios/issues/307

Marden answered 17/8, 2017 at 23:10 Comment(0)
M
5

Subscribe method should be added in this didReceiveRegistrationToken method, so that whenever the token is refreshed, the topic will be subscribed automatically.

func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {

Messaging.messaging().subscribe(toTopic: "TestTopic"){ error in
            if error == nil{
                print("Subscribed to topic")
            }
            else{
                print("Not Subscribed to topic")
            }
        }
}
Montane answered 18/2, 2020 at 16:49 Comment(0)
L
2

Well in Firebase Messaging 4.0.4 add it to didRegisterForRemoteNotificationsWithDeviceToken Method, that will do the rest

 func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Messaging.messaging().apnsToken = deviceToken
        Messaging.messaging().subscribe(toTopic: hubId)
    }
Leland answered 7/11, 2017 at 7:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.