|---|---|
| **Select platform:** | [iOS+](https://firebase.google.com/docs/cloud-messaging/ios/get-started.md.txt) [Android](https://firebase.google.com/docs/cloud-messaging/android/get-started.md.txt) [Web](https://firebase.google.com/docs/cloud-messaging/web/get-started.md.txt) [Flutter](https://firebase.google.com/docs/cloud-messaging/flutter/get-started.md.txt) [Unity](https://firebase.google.com/docs/cloud-messaging/unity/get-started.md.txt) [C++](https://firebase.google.com/docs/cloud-messaging/cpp/get-started.md.txt) |

<br />

This guide describes how to get started with Firebase Cloud Messaging in your
Apple platform (like iOS) client apps so that you can reliably send messages.

For Apple client apps, you can receive notification and data payloads up to 4096
bytes over the Firebase Cloud Messaging APNs interface.

To write your client code in Objective-C or Swift, we recommend that you use the
[FIRMessaging
API](https://firebase.google.com/docs/reference/ios/firebasemessaging/interface_f_i_r_messaging). The
[quickstart example](https://github.com/firebase/quickstart-ios/tree/master/messaging/)
provides sample code for both languages.

Before you get started, [add Firebase to your Apple project](https://firebase.google.com/docs/ios/setup.md.txt).

## Method swizzling in Firebase Cloud Messaging

The FCM SDK performs method swizzling in two key areas: mapping your
APNs token to [the Firebase Installation ID](https://firebase.google.com/docs/cloud-messaging/ios/get-started.md.txt#access-firebase-installation-id)
or FCM registration token and capturing analytics data during
[downstream message callback
handling](https://firebase.google.com/docs/cloud-messaging/ios/receive-messages#handle-messages-swizzling-disabled).
Developers who prefer not to use swizzling can disable it by adding the flag
`FirebaseAppDelegateProxyEnabled` in the app's `Info.plist` file and setting
it to the boolean value `NO`. Relevant areas of the guides provide code
examples, both with and without method swizzling enabled.

> [!IMPORTANT]
> **Important:** With the Firebase Unity SDK on iOS, **do not disable method
> swizzling.** Swizzling is required by the SDK, and without it key Firebase features such as FCM registration handling don't function properly.

## Upload your APNs authentication key


Upload your APNs authentication key to Firebase. If you don't already have an
APNs authentication key, make sure to create one in the
[Apple Developer Member Center](https://developer.apple.com/membercenter/index.action).

1. In the Firebase console, go to **Settings** \> **General** . Then, click the [**Cloud Messaging** tab](https://console.firebase.google.com/project/_/settings/cloudmessaging).
2. In **APNs authentication key** under **iOS app configuration** , click **Upload** to upload your development authentication key, or production authentication key, or both. At least one is required.
3. Browse to the location where you saved your key, select it, and click **Open** . Add the key ID for the key (available in the [Apple Developer Member Center](https://developer.apple.com/membercenter/index.action)) and click **Upload**.

## Register for remote notifications

Either at startup, or at the desired point in your application flow, register your app for remote notifications. Call `registerForRemoteNotifications` as shown:

> [!NOTE]
> Note: SwiftUI apps should use the `UIApplicationDelegateAdaptor` or `NSApplicationDelegateAdaptor` property wrappers to provide a type corresponding to the appropriate app delegate protocol.

#### Swift

```swift
UNUserNotificationCenter.current().delegate = self

let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
  options: authOptions,
  completionHandler: { _, _ in }
)

application.registerForRemoteNotifications()
```

#### Objective-C

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

[application registerForRemoteNotifications];
```

> [!CAUTION]
> You must assign the UNUserNotificationCenter's [`delegate`](https://developer.apple.com/documentation/usernotifications/unusernotificationcenter/1649522-delegate) property and FIRMessaging's [`delegate`](https://firebase.google.com/docs/reference/ios/firebasemessaging/api/reference/Classes/FIRMessaging.md.txt#delegate) property. For example, in an iOS app, assign it in the `applicationWillFinishLaunchingWithOptions:` or `applicationDidFinishLaunchingWithOptions:` method of the app delegate.

## Access the Firebase Installation ID

> [!TIP]
> **Tip:** See [Best practices for FCM registration
> management](https://firebase.google.com/docs/cloud-messaging/manage-tokens) for tips on managing registrations.

> [!CAUTION]
> Apps still using [deprecated Instance ID APIs](https://firebase.google.com/docs/projects/manage-installations.md.txt#fid-iid) for registration management should update all registration logic to use the FCM APIs described here.


By default, the FCM SDK registers the app instance with
FCM and returns a [Firebase Installation ID (FID)](https://firebase.google.com/docs/projects/manage-installations.md.txt) for the client app instance on app
launch. Similar to the APNs device token, this FID allows you to send targeted
notifications to any particular instance of your app.

In the same way that Apple platforms typically deliver an APNs device token at
app startup, FCM provides an FID for targeting notifications. The
FCM SDK delivers the FID using the `FIRMessagingDelegate`'s
[`messaging:didReceiveRegistration:`](https://firebase.google.com/docs/reference/swift/firebasemessaging/api/reference/Protocols/MessagingDelegate.md.txt#messaging_:didreceiveregistration:) method, automatically monitors
for FID changes, and invokes the method with a new FID when a change is detected.
We recommend that you retrieve and upload the FID regularly because the FID
can rotate after the initial startup.
For details on when FIDs are reissued and how to manually monitor them, see [Monitor the
Firebase installation ID lifecycle](https://firebase.google.com/docs/projects/manage-installations#monitor-id-lifecycle).

### Enable registration using Firebase Installation ID

To enable registering your app instance with FCM using
[Firebase Installation ID (FID)](https://firebase.google.com/docs/projects/manage-installations.md.txt),
add the following metadata flag to your `Info.plist` file, not
your `GoogleService-Info.plist` file:

`FirebaseMessagingInstallationIdEnabled = YES`

### Set the messaging delegate

To receive FIDs, implement the messaging delegate
protocol and set the `delegate` property of
`FIRMessaging` after calling `[FIRApp configure]`.
For example, if your application delegate conforms to the messaging delegate
protocol, you can set the delegate on `application:didFinishLaunchingWithOptions:`
to itself.

#### Swift

```swift
Messaging.messaging().delegate = self
```

#### Objective-C

```objective-c
[FIRMessaging messaging].delegate = self;
```

### Implement the `didReceiveRegistration` method


App instances are targeted using the FID once registration completes.
To receive the FID upon registration, implement the
[`messaging:didReceiveRegistration:`](https://firebase.google.com/docs/reference/swift/firebasemessaging/api/reference/Protocols/MessagingDelegate.md.txt#messaging_:didreceiveregistration:) method.
This method is typically invoked once per app startup with the FID. When this
method is called, you can perform the following actions:

- If you haven't sent the FID to your server, or sent the FID recently, send it to your application server.
- If the subscription is new or the user re-installed the app, subscribe the FID to topics.

#### Swift

```swift
func messaging(_ messaging: Messaging, didReceiveRegistration installationId: String?) {
  print("Firebase Installation ID: \(String(describing: installationId))")
  // Note: This callback is fired at each app startup.

  if let installationId = installationId {
    // Send the Firebase Installation ID to your app server.
    sendRegistrationToServer(installationId)
  }
}
    
```

#### Objective-C

```objective-c
- (void)messaging:(FIRMessaging *)messaging didReceiveRegistration:(nullable NSString *)installationId {
  NSLog(@"Firebase Installation ID: %@", installationId);
  // Note: This callback is fired at each app startup.

  if (installationId != nil) {
    // Send the Firebase Installation ID to your app server.
    [self sendRegistrationToServer:installationId];
  }
}
    
```

### Manually register when auto-initialization is disabled

If you have disabled auto-initialization, the FCM SDK won't automatically register
the app instance with FCM at app startup. You must call
[`register`](https://firebase.google.com/docs/reference/swift/firebasemessaging/api/reference/Classes/Messaging.md.txt#register)
on app startup to trigger registration and FID delivery through the
[`messaging:didReceiveRegistration:`](https://firebase.google.com/docs/reference/swift/firebasemessaging/api/reference/Protocols/MessagingDelegate.md.txt#messaging_:didreceiveregistration:) method:

#### Swift

```swift
// Trigger manual registration if auto-initialization is turned off.
Messaging.messaging().register { error in
    if let error = error {
        // Handle the error
        print("Failed registering: \(error)")
        return
    }
    // Registration was successful. FID is delivered through the messaging:didReceiveRegistration: method.
    print("Successfully registered.")
}
    
```

#### Objective-C

```objective-c
// Trigger manual registration if auto-initialization is turned off.
[[FIRMessaging messaging] registerWithCompletion:^(NSError * _Nullable error) {
    if (error) {
        // Handle the error
        NSLog(@"Failed registering: %@", error);
        return;
    }
    // Registration was successful. FID is delivered through the messaging:didReceiveRegistration: method.
    NSLog(@"Successfully registered.");
}];
    
```

#### Swizzling disabled: mapping your APNs token and FID

If you've disabled method swizzling or you're building a SwiftUI app,
you must explicitly map your APNs token to the Firebase Installation IDs (FID). Implement the
`application(_:didRegisterForRemoteNotificationsWithDeviceToken:)` method to
retrieve the APNs token, and then set the
[`apnsToken`](https://firebase.google.com/docs/reference/swift/firebasemessaging/api/reference/Classes/Messaging.md.txt#apnstoken)
property of `Messaging`:

#### Swift

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

#### Objective-C

```objective-c
// With "FirebaseAppDelegateProxyEnabled": NO
- (void)application:(UIApplication *)application
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    [FIRMessaging messaging].APNSToken = deviceToken;
}
```

Once the FID is registered, you can access it and listen for refresh
events using the same methods as when swizzling is enabled.

## Access the registration token (deprecated)

> [!CAUTION]
> **Caution:** This feature is deprecated. Use [Firebase Installation
> IDs](https://firebase.google.com/docs/cloud-messaging/ios/get-started#access-firebase-installation-id), as this method will be removed in a future release.

> [!TIP]
> **Tip:** See [Best practices for FCM registration
> management](https://firebase.google.com/docs/cloud-messaging/manage-tokens) for tips on managing registrations.


By default, the FCM SDK generates a registration token for the
client app instance on app launch. Similar to the APNs device token, this
token lets you send targeted notifications to any particular instance of your
app.


In the same way that Apple platforms typically deliver an APNs device token on
app start, FCM provides a registration token via
`FIRMessagingDelegate`'s
`messaging:didReceiveRegistrationToken:` method. The FCM SDK
retrieves a new or existing token during initial app launch and whenever the
token is updated or invalidated. In all cases, the FCM SDK calls
`messaging:didReceiveRegistrationToken:` with a valid token.

> [!CAUTION]
> Apps still using [deprecated Instance ID APIs](https://firebase.google.com/docs/projects/manage-installations.md.txt#fid-iid) for registration management should update all registration logic to use the FCM APIs described here.


The registration token can change when:

- The app is restored on a new device.
- The user uninstalls or reinstalls the app.
- The user clears app data.

### Set the messaging delegate


To receive registration tokens, implement the messaging delegate protocol and
set `FIRMessaging`'s `delegate` property after calling
`[FIRApp configure]`. For example, if your application delegate
conforms to the messaging delegate protocol, you can set the delegate on
`application:didFinishLaunchingWithOptions:` to itself.

#### Swift

```swift
Messaging.messaging().delegate = self
```

#### Objective-C

```objective-c
[FIRMessaging messaging].delegate = self;
```

### Fetch the current registration token


Registration tokens are delivered through the
`messaging:didReceiveRegistrationToken:` method. This method is
generally called once per app start with a registration token. When this
method is called, it's the ideal time to:

- If the registration token is new, send it to your application server.
- Subscribe the registration token to topics. This is required only for new subscriptions or for situations where the user has re-installed the app.


You can retrieve the token directly using
[token(completion:)](https://firebase.google.com/docs/reference/swift/firebasemessaging/api/reference/Classes/Messaging.md.txt#tokencompletion:).
A non-null error is provided if the token retrieval fails in any way.

#### Swift

```swift
Messaging.messaging().token { token, error in
  if let error = error {
    print("Error fetching remote FCM registration token: \(error)")
  } else if let token = token {
    print("Remote instance ID token: \(token)")
  }
}
```

#### Objective-C

```objective-c
[[FIRMessaging messaging] tokenWithCompletion:^(NSString * _Nullable token, NSError * _Nullable error) {
  if (error != nil) {
    NSLog(@"Error fetching the remote FCM registration token: %@", error);
  } else {
    NSLog(@"Remote FCM registration token: %@", token);
    NSString* message =
      [NSString stringWithFormat:@"FCM registration token: %@", token];
    // display message
    NSLog(@"%@", message);
  }
}];
```


You can use this method at any time to access the token instead of storing it.

### Monitor token refresh


To be notified whenever the token is updated, supply a delegate conforming to
the messaging delegate protocol. The following example registers the delegate
and adds the proper delegate method:

#### Swift

```swift
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
  print("Firebase registration token: \(String(describing: fcmToken))")
  // TODO: If necessary send token to application server.
  // Note: This callback is fired at each app startup and whenever a new token is generated.
}
```

#### Objective-C

```objective-c
- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken {
    NSLog(@"FCM registration token: %@", fcmToken);
    // Notify about received token.
    NSDictionary *dataDict = [NSDictionary dictionaryWithObject:fcmToken forKey:@"token"];
    [[NSNotificationCenter defaultCenter] postNotificationName:
     @"FCMToken" object:nil userInfo:dataDict];
    // TODO: If necessary send token to application server.
    // Note: This callback is fired at each app startup and whenever a new token is generated.
}
```


Alternatively, you can listen for an `NSNotification` named
`kFIRMessagingRegistrationTokenRefreshNotification` rather than
supplying a delegate method. The token property always has the current token
value.

#### Swizzling disabled: mapping your APNs token and registration token

If you have disabled method swizzling, or you are building a SwiftUI app, you'll need to
explicitly map your APNs token to the FCM registration token. Implement the
`application(_:didRegisterForRemoteNotificationsWithDeviceToken:)` method to
retrieve the APNs token, and then set `Messaging`'s
[`apnsToken`](https://firebase.google.com/docs/reference/swift/firebasemessaging/api/reference/Classes/Messaging.md.txt#apnstoken)
property:

#### Swift

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

#### Objective-C

```objective-c
// With "FirebaseAppDelegateProxyEnabled": NO
- (void)application:(UIApplication *)application
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    [FIRMessaging messaging].APNSToken = deviceToken;
}
```

After the FCM registration token is generated, you can access it
and listen for refresh events using the same methods as with swizzling
enabled.

## Prevent auto initialization

When a FCM registration is generated, the library uploads the
identifier and configuration data to Firebase. If you want to get an explicit
opt-in from users first, you can prevent auto registration at configure time by
disabling FCM. To do this, add a metadata value to your `Info.plist` (not your
`GoogleService-Info.plist`):

`FirebaseMessagingAutoInitEnabled = NO`

To re-enable FCM, you can make a runtime call:

#### Swift

```swift
Messaging.messaging().autoInitEnabled = true
```

#### Objective-C

```objective-c
[FIRMessaging messaging].autoInitEnabled = YES;
```

This value persists across app restarts once set.

## Set up the notification service extension

To send notifications that include images to Apple devices, you must add a
notification service extension. This extension allows devices to display images
delivered in the notification payload. If you don't plan to send images in
notifications, you can skip this step.

To add a service extension, perform the required setup tasks for [modifying and
presenting
notifications](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ModifyingNotifications.html)
in APNs, and then add the FCM extension helper API in `NotificationService.m`.
Specifically, instead of completing the callback with
`self.contentHandler(self.bestAttemptContent);`, complete it with `FIRMessaging
extensionHelper` as shown:

    @interface NotificationService () <NSURLSessionDelegate>
    @property(nonatomic) void (^contentHandler)(UNNotificationContent *contentToDeliver);
    @property(nonatomic) UNMutableNotificationContent *bestAttemptContent;
    @end

@implementation NotificationService

    - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
        self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];

        // Modify the notification content here as you want
    self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [modified]",
    self.bestAttemptContent.title];

      // Call FIRMessaging extension helper API.
      [[FIRMessaging extensionHelper] populateNotificationContent:self.bestAttemptContent
    withContentHandler:contentHandler];

    }
    ...

## Send a notification message

1. Install and run the app on the target device. On Apple devices, accept the
   request for permission to receive remote notifications.

2. Check that the app is in the background on the device.

3. In the Firebase console, go to
   **DevOps \& Engagement** \> [**Messaging**](https://console.firebase.google.com/project/_/messaging/)

4. Create a campaign.

   - If this is your first message:

     1. Select **Create your first campaign**.

     2. Select **Firebase Notification messages** and select **Create**.

   - If you have previously created campaigns:

     1. On the **Campaigns** tab, select **New campaign**.

     2. Click **Notifications**.

5. Enter the message text.

6. Select **Send test message** from the right pane.

7. In the field labeled **Add a Firebase Installation ID or FCM
   registration token**, enter your registration token.

8. Select **Test**.

After you select **Test**, the targeted client device, with the app in the
background, should receive the notification.

For insight into message delivery to your app, go to the
**DevOps \& Engagement** \> **Messaging** \>
[**Reports** dashboard](https://console.firebase.google.com/project/_/notification/reporting)
in the Firebase console. This dashboard records the number of messages sent
and opened on Apple and Android devices, along with data for "impressions"
(notifications seen by users) for Android apps.

## Next steps

After you have completed the setup steps, here are a few options for moving
forward with FCM for Apple platforms:

- [Send messages to devices](https://firebase.google.com/docs/cloud-messaging/server-environment.md.txt)
- [Receive messages in an Apple app](https://firebase.google.com/docs/cloud-messaging/receive-messages.md.txt?platform=ios)
- [Send messages to topics](https://firebase.google.com/docs/cloud-messaging/topic-messaging.md.txt)