source

FCM에 대한 올바른 토큰 검색 방법 - iOS 10 Swift 3

manycodes 2023. 7. 5. 20:50
반응형

FCM에 대한 올바른 토큰 검색 방법 - iOS 10 Swift 3

저는 Firebase와 함께 Firebase를 구현했습니다.인증/FCM 등이 Firebase Console을 통해 성공적으로 알림을 전송했습니다.

하지만 저는 제 앱 서버에서 알림을 푸시해야 합니다.

아래에서 장치의 등록 ID를 검색하는 올바른 방법이 무엇인지 궁금합니다.

didRegisterForRemoteNotification에서 등록 ID 토큰 검색장치 포함상품권

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    var token = ""

    for i in 0..<deviceToken.count {
        token += String(format: "%02.2hhx", arguments: [deviceToken[i]])
    }

    print("Registration succeeded!")
    print("Token: ", token)
    Callquery(token)

}

Firebase에서 등록 토큰 검색(현재 등록 토큰을 검색하는 Firebase 문서 기반)

let token = FIRInstanceID.instanceID().token()!

첫 번째 방법을 사용하고 있었는데, 등록 ID가 앱 서버 데이터베이스에 저장되어 있음에도 푸시 알림이 수신되지 않고 있으며 이 CURL 세션 결과가 나타납니다.

{"multicast_id":6074293608087656831,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidRegistration"}]}

저도 두 번째 방법을 시도했는데 아래와 같이 앱을 실행하는 동안 치명적인 오류가 발생했습니다:-

누군가 나에게 올바른 길을 알려주면 감사합니다, 감사합니다!

tokenRefreshNotification앱을 실행할 때 항상 함수가 호출되는 것은 아닙니다.

단, 정규 내부에 코드를 배치할 경우didRegisterForRemoteNotificationsWithDeviceToken대리자 기능, 나는 항상 토큰을 얻을 수 있습니다.

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    if let refreshedToken = InstanceID.instanceID().token() {
        print("InstanceID token: \(refreshedToken)")
    }
}

(스위프트 3 + Firebase 4.0.4)

Firebase 권장 방법:

let token = Messaging.messaging().fcmToken

참조: iOS에서 Firebase Cloud Messaging Client설정

Swift 3 + Firebase 4.0.4 :

static var FirebaseToken : String? {
    return InstanceID.instanceID().token()
}

Swift 4 + Firebase(5.3.0)

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    InstanceID.instanceID().instanceID(handler: { (result, error) in
        if let error = error {
            print("Error fetching remote instange ID: \(error)")
        } else if let result = result {
            print("Remote instance ID token: \(result.token)")
        }
    })
}

스위프트 4

제공처: https://stackoverflow.com/a/50945350/1014164

InstanceID.instanceID().instanceID { (result, error) in
    if let error = error {
        print("Error fetching remote instange ID: \(error)")
    } else if let result = result {
        print("Remote instance ID token: \(result.token)")
    }
}

FCM 장치 토큰 swift3

    let fcmDeviceToken = FIRInstanceID.instanceID().token()
    print("FCM token: \(fcmDeviceToken ?? "")")

두 번째 옵션을 선택하면, 이것은 정말 어리석고 단순해 보일 것이지만, 선택적인 치명적인 오류를 해결하려면 마지막에 강제로 포장을 풀면 됩니다.

코드:
var token = FIRInstanceID.instanceID().token()!
제작:
var token = FIRInstanceID.instanceID().token()

그럼 적어도 그 끔찍한 충돌은 해결될 겁니다.

Firebase 토큰 새로 고침 알림에 대한 첫 번째 등록:

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

그런 다음 토큰 새로 고침 알림 선택기에서 토큰을 받을 수 있습니다.

func tokenRefreshNotification(_ notification: Notification) {
    if let refreshedToken = FIRInstanceID.instanceID().token() {
      print("InstanceID token: \(refreshedToken)")
    }

    // Connect to FCM since connection may have failed when attempted before having a token.
    connectToFcm()
}

현재 FCM 토큰을 가져오려면

if let token = Messaging.messaging().fcmToken {
    // token is current fcmToken
}

현재 FCM 토큰을 갱신하려면

현재 instanceId를 삭제하면 잠시 후 MessagingDelegate(messaging:didReceiveRegistrationToken)를 통해 새 토큰이 수신됩니다.

InstanceID.instanceID().deleteID { (error) in
    if let er = error {
        print(er.localizedDescription)
    } else {
        print("instanceID().deleteID  success ---------------➤")
    }
}

저도 같은 문제를 겪고 있었지만, 무슨 일이 일어나고 있는지 알 수 없었습니다.

didRegisterForRemoteNotificationsWithDeviceToken@Sam에서 제안하는 것은 매번 (거의) 호출되기 때문에 좋은 방법이지만, 새로 고침된 토큰으로 앱을 처음 열 때는 호출되지 않습니다.

따라서 이 시나리오에서는 다음이 필요합니다.

func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
    print("Refreshed Token: \(fcmToken)")
}

따라서 다음만 사용하면 됩니다.

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    if let fcmToken = InstanceID.instanceID().token() {
        print("InstanceID token: \(fcmToken)")
    }
}

사용자가 앱을 두 번째로 열 때만 "새로 고침된 토큰"을 받을 수 있습니다.

앱을 제거하고 빌드 폴더(Product > Clean Build Folder)를 정리하여 새로 고침 토큰을 강제로 실행할 수 있었습니다.테스트하기 좋습니다.

이상적으로는 모든 것을 처리할 수 있습니다.messaging:didReceiveRegistrationToken대리인 방법이지만 작동할 수 없었습니다.FCM 토큰 변경에 대한 알림을 받는 또 다른 방법은 수신 대기입니다.NSNotification이름 지어진kFIRMessagingRegistrationTokenRefreshNotification설명서에 제시된 바와 같이, https://firebase.google.com/docs/cloud-messaging/ios/client

먼저 다음과 같은 라이브러리를 가져옵니다.

import FirebaseInstanceID
import FirebaseMessaging
import UserNotifications

대리자 설정:메시징 대표자, UN 사용자 알림 센터 대표자

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

이 코드를 didFinishLaunching()에 기록합니다.

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    
    // Override point for customization after application launch.
    FirebaseApp.configure()
    Messaging.messaging().delegate = self
    
    //remote Notifications
    if #available(iOS 10.0, *) {
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (isGranted, err) in
            if err != nil {
                //Something bad happend
            } else {
                UNUserNotificationCenter.current().delegate = self
                Messaging.messaging().delegate = self
                
                DispatchQueue.main.async {
                    UIApplication.shared.registerForRemoteNotifications()
                }
            }
        }
    } else {
        // Fallback on earlier versions
    }
    
    if #available(iOS 10, *) {
        UNUserNotificationCenter.current().requestAuthorization(options: [.badge,.sound,.alert], completionHandler: { (granted, error) in
            application.registerForRemoteNotifications()
        })
    }else{
        let notificationSettings = UIUserNotificationSettings(types: [.badge,.sound,.alert], categories: nil)
        UIApplication.shared.registerUserNotificationSettings(notificationSettings)
        UIApplication.shared.registerForRemoteNotifications()
    }
    
    return true
}

쓰기 연결FCM 방법은 다음과 같습니다.

func ConnectToFCM() {
    Messaging.messaging().shouldEstablishDirectChannel = true
    
    if let token = InstanceID.instanceID().token() {
        print("\n\n\n\n\n\n\n\n\n\n ====== TOKEN DCS: " + token)
    }

푸시 알림을 등록하고 수신하는 대리자 방법도 작성합니다.

func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
    print("\n\n\n\n\n ==== FCM Token:  ",fcmToken)
    HelperFunction.helper.storeInUserDefaultForKey(name: kFCMToken, val: fcmToken)
    ConnectToFCM()
}

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    
   // UIApplication.shared.applicationIconBadgeNumber += 1
    
    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "Barker"), object: nil)
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
   
    print(userInfo)
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                 fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    
    print(userInfo)
    
    completionHandler(UIBackgroundFetchResult.newData)
}
        
}

이제 우리는 파이어베이스 콘솔에서 테스트할 수 있습니다.

100% 작동, 간편하고 테스트 완료

참고:

  1. xcode의 기능 섹션에서 푸시 알림을 활성화합니다.

  2. 파이어베이스 프로젝트 설정에 업로드된 두 p12 인증서를 두 번 확인합니다.

  3. 장치 토큰은 시뮬레이터가 아닌 실제 장치에서만 가져올 수 있습니다.

우선 필요한 모든 립을 가져와야 합니다.

import Firebase
import UserNotifications

나중에 AppDelegate.swift에서 다음 함수를 호출합니다.

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    Messaging.messaging().apnsToken = deviceToken

    InstanceID.instanceID().instanceID { (result, error) in
        if let error = error {
            print("Error fetching remote instance ID: \(error)")
        } else if let result = result {
            print("Remote instance ID token: \(result.token)")
        }
    }
}

MessagingDelegate 프로토콜을 확인합니다.

그런 다음 아래의 위임 방법을 추가하고 Firebase 토큰을 얻을 수 있습니다. (설명 https://firebase.google.com/docs/cloud-messaging/ios/client )

func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
        // send to remote server
        InstanceID.instanceID().instanceID { result, error in
            if let error = error {
                print("Error fetching remote instance ID: \(error)")
            } else if let result = result {
                print("Remote instance ID token: \(result.token)")
            }
        }
    }

이 질문은 오래되었지만 누군가 목표 C에서 사용하기를 원하는 경우에는 여전히 유효합니다.

최신 파이어베이스: 6.27.0

iOS 목표 C에서 우리는 이렇게 사용할 수 있습니다.

[[FIRInstanceID instanceID] instanceIDWithHandler:^(FIRInstanceIDResult * _Nullable result,
                                                            NSError * _Nullable error) {
            if (error != nil) {
                NSLog(@"Error : %@", error);
            } else {
                token = result.token;
            }
            NSLog(@"Token %@", result.token);
           
        }];

인스턴스 ID를 가져오려면:

 [[FIRInstanceID instanceID] getIDWithHandler:^(NSString *identity, NSError *error) {
         if (error != nil) {
           NSLog(@"Error : %@", error);
         } else {
           NSLog(@"instance ID: %@", identity);
         }
         NSLog(@"IID %@", identity);
       }];
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {        
    Messaging.messaging().apnsToken = deviceToken

    let deviceTokenString = deviceToken.reduce("") { $0 + String(format: "%02X", $1) }

    print("APNs device token: \(deviceTokenString)"
}

언급URL : https://stackoverflow.com/questions/40013764/correct-way-to-retrieve-token-for-fcm-ios-10-swift-3

반응형