Reputation: 5390
I am working with Firebase to enable push notifications on the app. Following the guidelines of Firebase
NSString *fcmToken = [FIRMessaging messaging].FCMToken;
This line of code is causing a build error: FCMToken not found on FIRMessaging object.
Knowing that I have imported:
#import <Firebase/Firebase.h>
#import <FirebaseAnalytics/FirebaseAnalytics.h>
#import <FirebaseInstanceID/FirebaseInstanceID.h>
#import <UserNotifications/UserNotifications.h>
#import <FirebaseMessaging/FIRMessaging.h>
I have also added: UNUserNotificationCenterDelegate, FIRMessagingDelegate
@interface myAppDelegate : NSObject <UIApplicationDelegate, UNUserNotificationCenterDelegate, FIRMessagingDelegate> {
I have also tried the following approach to get the token:
- (void)tokenRefreshNotification:(NSNotification *)notification {
NSString *tokenId = [[FIRInstanceID instanceID] token];
NSLog(@"FCM registration token: %@", tokenId);
}
But generated token is always equal to null.
This is the whole code used for token
// 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];
}
I've also tried the following to get token:
- (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];
}
When I try to use this token on Firebase I get invalid token and this a sample token I got:
7da8917e48dd7d09c7c0e537abd08fcab1778be73738052ef70e0f6e27a7015e
Upvotes: 1
Views: 5311
Reputation: 539
Are you running on iOS 10 or later? If yes, then you should set remoteMessageDelegate
.
Please have a look into below code :
[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 Class
#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 `[email protected]`.
* @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
You can install the files through Cocoa Pods by using pod 'Firebase/Messaging'
. For more information, Please have a look into https://firebase.google.com/docs/ios/setup.
Hopefully this will help.
Upvotes: 3
Reputation: 508
> - (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);
}
Upvotes: 1