繁体   English   中英

Firebase 令牌生成 iOS

[英]Firebase token generation iOS

我正在与 Firebase 合作以在应用上启用推送通知。 遵循 Firebase 的准则

NSString *fcmToken = [FIRMessaging messaging].FCMToken;

这行代码导致构建错误:在 FIRMessaging 对象上找不到 FCMToken。

知道我已经进口:

#import <Firebase/Firebase.h>
#import <FirebaseAnalytics/FirebaseAnalytics.h>
#import <FirebaseInstanceID/FirebaseInstanceID.h>
#import <UserNotifications/UserNotifications.h>
#import <FirebaseMessaging/FIRMessaging.h>

我还添加了:UNUserNotificationCenterDelegate、FIRMessagingDelegate

 @interface myAppDelegate : NSObject <UIApplicationDelegate, UNUserNotificationCenterDelegate, FIRMessagingDelegate> {

我还尝试了以下方法来获取令牌:

  - (void)tokenRefreshNotification:(NSNotification *)notification {
         NSString *tokenId = [[FIRInstanceID instanceID] token];
         NSLog(@"FCM registration token: %@", tokenId);
  }

但是生成的令牌总是等于空。

这是用于令牌的整个代码

 // this is always getting null value
 - (void)tokenRefreshNotification:(NSNotification *)notification {

        NSString *tokenId = [[FIRInstanceID instanceID] token];
        [self connectToFcm];
        [tokenId retain];
 }

 - (void)connectToFcm {
     if(gotConnected)
     {
         return;
     }
     [[FIRMessaging messaging] connectWithCompletion:^(NSError * _Nullable error) {
         if (error != nil) {
             NSLog(@"Unable to connect to FCM. %@", error);
         } else {
             gotConnected = true;
             NSLog(@"Connected to FCM.");
         }
     }];
 }

 //this is never getting called
 - (void)messaging:(nonnull FIRMessaging *)messaging didRefreshRegistrationToken:(nonnull NSString *)fcmToken
 {
     NSLog(@"didRefreshRegistrationToken fcmToken: %@", fcmToken);
 }

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

 {
       [FIRApp configure];
       [UNUserNotificationCenter currentNotificationCenter].delegate = self;
       UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
       [[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) {}];

    [[UIApplication sharedApplication] registerForRemoteNotifications];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(tokenRefreshNotification:) name:kFIRInstanceIDTokenRefreshNotification object:nil];
}

我还尝试了以下方法来获取令牌:

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

    [[FIRInstanceID instanceID] setAPNSToken:deviceToken type:FIRInstanceIDAPNSTokenTypeProd];
    NSLog(@"deviceToken %@", deviceToken);
    NSString * token = [NSString stringWithFormat:@"%@", deviceToken];
    //Format token as you need:
    token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
    token = [token stringByReplacingOccurrencesOfString:@">" withString:@""];
    token = [token stringByReplacingOccurrencesOfString:@"<" withString:@""];
    NSLog(@"token %@", token);
    tokenId = token;
    [self connectToFcm];
}

当我尝试在 Firebase 上使用此令牌时,我得到无效令牌,这是我得到的示例令牌:

7da8917e48dd7d09c7c0e537abd08fcab1778be73738052ef70e0f6e27a7015e

您是否在 iOS 10 或更高版本上运行? 如果是,那么您应该设置remoteMessageDelegate

请查看以下代码:

[FIRApp configure];

if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
        UIUserNotificationType allNotificationTypes =
        (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
        UIUserNotificationSettings *settings =
        [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    } else {
        // iOS 10 or later
#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
        UNAuthorizationOptions authOptions =
        UNAuthorizationOptionAlert
        | UNAuthorizationOptionSound
        | UNAuthorizationOptionBadge;
        [[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) {
        }];

        // For iOS 10 display notification (sent via APNS)
        [UNUserNotificationCenter currentNotificationCenter].delegate = self;
        // For iOS 10 data message (sent via FCM)
        [FIRMessaging messaging].remoteMessageDelegate = self;
#endif
    }

    [[UIApplication sharedApplication] registerForRemoteNotifications];
    NSLog(@"fir token is %@",[[FIRInstanceID instanceID] token]);

FIRMessaging.h 类

#import <Foundation/Foundation.h>

/**
 *  The completion handler invoked once the data connection with FIRMessaging is
 *  established.  The data connection is used to send a continous stream of
 *  data and all the FIRMessaging data notifications arrive through this connection.
 *  Once the connection is established we invoke the callback with `nil` error.
 *  Correspondingly if we get an error while trying to establish a connection
 *  we invoke the handler with an appropriate error object and do an
 *  exponential backoff to try and connect again unless successful.
 *
 *  @param error The error object if any describing why the data connection
 *               to FIRMessaging failed.
 */
typedef void(^FIRMessagingConnectCompletion)(NSError * __nullable error);

/**
 *  Notification sent when the upstream message has been delivered
 *  successfully to the server. The notification object will be the messageID
 *  of the successfully delivered message.
 */
FOUNDATION_EXPORT NSString * __nonnull const FIRMessagingSendSuccessNotification;

/**
 *  Notification sent when the upstream message was failed to be sent to the
 *  server.  The notification object will be the messageID of the failed
 *  message. The userInfo dictionary will contain the relevant error
 *  information for the failure.
 */
FOUNDATION_EXPORT NSString * __nonnull const FIRMessagingSendErrorNotification;

/**
 *  Notification sent when the Firebase messaging server deletes pending
 *  messages due to exceeded storage limits. This may occur, for example, when
 *  the device cannot be reached for an extended period of time.
 *
 *  It is recommended to retrieve any missing messages directly from the
 *  server.
 */
FOUNDATION_EXPORT NSString * __nonnull const FIRMessagingMessagesDeletedNotification;

/**
 *  @enum FIRMessagingError
 */
typedef NS_ENUM(NSUInteger, FIRMessagingError) {
  /// Unknown error.
  FIRMessagingErrorUnknown = 0,

  /// FIRMessaging couldn't validate request from this client.
  FIRMessagingErrorAuthentication = 1,

  /// InstanceID service cannot be accessed.
  FIRMessagingErrorNoAccess = 2,

  /// Request to InstanceID backend timed out.
  FIRMessagingErrorTimeout = 3,

  /// No network available to reach the servers.
  FIRMessagingErrorNetwork = 4,

  /// Another similar operation in progress, bailing this one.
  FIRMessagingErrorOperationInProgress = 5,

  /// Some parameters of the request were invalid.
  FIRMessagingErrorInvalidRequest = 7,
};

/// Status for the downstream message received by the app.
typedef NS_ENUM(NSInteger, FIRMessagingMessageStatus) {
  /// Unknown status.
  FIRMessagingMessageStatusUnknown,
  /// New downstream message received by the app.
  FIRMessagingMessageStatusNew,
};

/// Information about a downstream message received by the app.
@interface FIRMessagingMessageInfo : NSObject

/// The status of the downstream message
@property(nonatomic, readonly, assign) FIRMessagingMessageStatus status;

@end

/**
 * A remote data message received by the app via FCM (not just the APNs interface).
 *
 * This is only for devices running iOS 10 or above. To support devices running iOS 9 or below, use
 * the local and remote notifications handlers defined in UIApplicationDelegate protocol.
 */
@interface FIRMessagingRemoteMessage : NSObject

/// The downstream message received by the application.
@property(nonatomic, readonly, strong, nonnull) NSDictionary *appData;

@end

/**
 * A protocol to receive data message via FCM for devices running iOS 10 or above.
 *
 * To support devices running iOS 9 or below, use the local and remote notifications handlers
 * defined in UIApplicationDelegate protocol.
 */
@protocol FIRMessagingDelegate <NSObject>

/// The callback to handle data message received via FCM for devices running iOS 10 or above.
- (void)applicationReceivedRemoteMessage:(nonnull FIRMessagingRemoteMessage *)remoteMessage;

@end

/**
 *  Firebase Messaging enables apps to communicate with their app servers
 *  using simple messages.
 *
 *  To send or receive messages, the app must get a
 *  registration token from GGLInstanceID, which authorizes an
 *  app server to send messages to an app instance. Pass your sender ID and
 *  `kGGLInstanceIDScopeFIRMessaging` as parameters to the method.
 *
 *  A sender ID is a project number created when you configure your API project.
 *  It is labeled "Project Number" in the Google Developers Console.
 *
 *  In order to receive FIRMessaging messages, declare application:didReceiveRemoteNotification:
 *
 *  Client apps can send upstream messages back to the app server using the XMPP-based
 *  <a href="https://developers.google.com/cloud-messaging/ccs.html">Cloud Connection Server</a>
 *
 */
@interface FIRMessaging : NSObject

/**
 * Delegate to handle remote data messages received via FCM for devices running iOS 10 or above.
 */
@property(nonatomic, weak, nullable) id<FIRMessagingDelegate> remoteMessageDelegate;

/**
 *  FIRMessaging
 *
 *  @return An instance of FIRMessaging.
 */
+ (nonnull instancetype)messaging NS_SWIFT_NAME(messaging());

/**
 *  Unavailable. Use +messaging instead.
 */
- (nonnull instancetype)init __attribute__((unavailable("Use +messaging instead.")));

#pragma mark - Connect

/**
 *  Create a FIRMessaging data connection which will be used to send the data notifications
 *  send by your server. It will also be used to send ACKS and other messages based
 *  on the FIRMessaging ACKS and other messages based  on the FIRMessaging protocol.
 *
 *  Use the `disconnect` method to disconnect the connection.
 *
 *  @see FIRMessagingService disconnect
 *
 *  @param handler  The handler to be invoked once the connection is established.
 *                  If the connection fails we invoke the handler with an
 *                  appropriate error code letting you know why it failed. At
 *                  the same time, FIRMessaging performs exponential backoff to retry
 *                  establishing a connection and invoke the handler when successful.
 */
- (void)connectWithCompletion:(nonnull FIRMessagingConnectCompletion)handler;

/**
 *  Disconnect the current FIRMessaging data connection. This stops any attempts to
 *  connect to FIRMessaging. Calling this on an already disconnected client is a no-op.
 *
 *  Call this before `teardown` when your app is going to the background.
 *  Since the FIRMessaging connection won't be allowed to live when in background it is
 *  prudent to close the connection.
 */
- (void)disconnect;

#pragma mark - Topics

/**
 *  Asynchronously subscribes to a topic.
 *
 *  @param topic The name of the topic, for example @"sports".
 */
- (void)subscribeToTopic:(nonnull NSString *)topic;

/**
 *  Asynchronously unsubscribe to a topic.
 *
 *  @param topic The name of the topic, for example @"sports".
 */
- (void)unsubscribeFromTopic:(nonnull NSString *)topic;

#pragma mark - Upstream

/**
 *  Sends an upstream ("device to cloud") message.
 *
 *  The message will be queued if we don't have an active connection.
 *  You can only use the upstream feature if your GCM implementation
 *  uses the XMPP-based Cloud Connection Server.
 *
 *  @param message      Key/Value pairs to be sent. Values must be String, any
 *                      other type will be ignored.
 *  @param to           A string identifying the receiver of the message. For GCM
 *                      project IDs the value is `SENDER_ID@gcm.googleapis.com`.
 *  @param messageID    The ID of the message. This is generated by the application. It
 *                      must be unique for each message generated by this application.
 *                      It allows error callbacks and debugging, to uniquely identify
 *                      each message.
 *  @param ttl          The time to live for the message. In case we aren't able to
 *                      send the message before the TTL expires we will send you a
 *                      callback. If 0, we'll attempt to send immediately and return
 *                      an error if we're not connected.  Otherwise, the message will
 *                      be queued.  As for server-side messages, we don't return an error
 *                      if the message has been dropped because of TTL; this can happen
 *                      on the server side, and it would require extra communication.
 */
- (void)sendMessage:(nonnull NSDictionary *)message
                 to:(nonnull NSString *)receiver
      withMessageID:(nonnull NSString *)messageID
         timeToLive:(int64_t)ttl;

#pragma mark - Analytics

/**
 *  Call this when the app received a downstream message. Used to track message
 *  delivery and analytics for messages. You don't need to call this if you
 *  don't set the `FIRMessagingAutoSetupEnabled` flag in your Info.plist. In the
 *  latter case the library will call this implicitly to track relevant
 *  messages.
 *
 *  @param message The downstream message received by the application.
 *
 *  @return Information about the downstream message.
 */
- (nonnull FIRMessagingMessageInfo *)appDidReceiveMessage:(nonnull NSDictionary *)message;

@end

您可以使用 pod 'Firebase/Messaging'通过 Cocoa Pods 安装文件。 有关更多信息,请查看https://firebase.google.com/docs/ios/setup

希望这会有所帮助。

> - (void) notificationRegister{
    [FIRApp configure];
    [self connectToFcm];
    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_9_x_Max) {
        UIUserNotificationType allNotificationTypes =
        (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
        UIUserNotificationSettings *settings =
        [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    } else {
        // iOS 10 or later
#if defined(__IPHONE_10_0) && IPHONE_OS_VERSION_MAX_ALLOWED >= IPHONE_10_0
        // For iOS 10 display notification (sent via APNS)
        [UNUserNotificationCenter currentNotificationCenter].delegate = self;
        UNAuthorizationOptions authOptions =
        UNAuthorizationOptionAlert
        | UNAuthorizationOptionSound
        | UNAuthorizationOptionBadge;
        [[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError * _Nullable error) {
        }];

        // For iOS 10 data message (sent via FCM)
        [FIRMessaging messaging].remoteMessageDelegate = self;
#endif
    }

    [[UIApplication sharedApplication] registerForRemoteNotifications];
}
- (void)connectToFcm {
    if (![[FIRInstanceID instanceID] token]) {
        return;
    }
    [[FIRMessaging messaging] disconnect];
    [[FIRMessaging messaging] connectWithCompletion:^(NSError * _Nullable error) {
        if (error != nil) {
            NSLog(@"Unable to connect to FCM. %@", error);
        } else {
            NSLog(@"Connected to FCM.");
        }
    }];
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    [[FIRInstanceID instanceID] setAPNSToken:deviceToken
                                        type:FIRInstanceIDAPNSTokenTypeSandbox];
    NSString *refreshedToken = [[FIRInstanceID instanceID] token];
    _strTokenId = refreshedToken;
}
- (void)tokenRefreshNotification:(NSNotification *)notification {
    NSString *refreshedToken = [[FIRInstanceID instanceID] token];
    NSLog(@"InstanceID token: %@", refreshedToken);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM