Skip to content

The Push Notifications Guide for Capacitor

Push notifications are one of the most commonly used features for mobile apps. In this guide, we will add push notifications to a Capacitor app with support for Android, iOS and the Web using the Firebase Cloud Messaging SDK.

Capacitor Push Notifications Demo

Capacitor Push Notifications Demo

For this we will create a new Ionic Capacitor app. First we will set up our Firebase project and configure the Capacitor App. Then we will add the Firebase Cloud Messaging SDK. Last but not least, we will test the implementation using the Firebase Console and the Firebase Admin SDK. This guide covers everything that is needed. If you have already done certain steps such as creating a Firebase project, just skip those steps. Let's get started!

Why Firebase?

With Firebase, Google offers a great mobile platform that lets you build high-quality apps very quickly and efficiently. Firebase Cloud Messaging is the cross-platform messaging solution that lets you reliably send messages at no cost. Also, Firebase has a huge community and great SDKs that you can use in your Capacitor project.

Preparation

First, we will create a new app, which we will then configure step-by-step.

Create a new App

To create a new project, we simply use the Ionic CLI. For this, first install the CLI globally:

npm i -g @ionic/cli

After that, create a new project with the ionic start command:

npx ionic start capacitor-firebase-messaging-demo blank --type=angular --capacitor --package-id=YOUR_PACKAGE_ID
Warning

Be sure to specify a unique identifier for the package-id. It must be in reverse domain name notation, generally representing a domain name that you or your company owns. In this example, dev.robingenz.capacitorjs.demo.firebasemessaging will be used as package-id. Choose a different identifier for your app.

In this case, the app is called capacitor-firebase-messaging-demo, the starter template is blank and the project type for the purposes of this guide is Angular. You can also choose Vue or React, for example. Additionally, we enable the Capacitor integration with --capacitor and set a custom package identifier.

Once everything is ready, you should see this output:

Your Ionic app is ready! Follow these next steps:

- Go to your new project: cd ./capacitor-firebase-messaging-demo
- Run ionic serve within the app directory to see your app in the browser
- Run ionic capacitor add to add a native iOS or Android project using Capacitor
- Generate your app icon and splash screens using cordova-res --skip-config --copy
- Explore the Ionic docs for components, tutorials, and more: https://ion.link/docs
- Building an enterprise app? Ionic has Enterprise Support and Features: https://ion.link/enterprise-edition

Add the Android platform

Install the @capacitor/android package and add the Android platform:

npm install @capacitor/android
npx cap add android

Add the iOS platform

Install the @capacitor/ios package and add the iOS platform:

npm install @capacitor/ios
npx cap add ios

Create a Firebase project

Before we can set up Firebase Cloud Messaging we need to create a Firebase project. If you already have a project, you can skip this step.

Go to the Firebase console and click the Add project button. Enter a project name and create the project.

Install the Firebase Cloud Messaging Plugin

We will use the Capacitor Firebase Cloud Messaging plugin to integrate the Firebase Cloud Messaging SDK into the app. Install the npm package and then synchronize the Capacitor project:

npm install @capacitor-firebase/messaging firebase
npx ionic cap sync

Now let's get started with the configuration of the different platforms.

Android

We will start with Android, as this is the easiest. We will go through all the steps in detail. Just skip the steps you have already done if you are applying the guide to an existing project.

Add Firebase to your Android App

Navigate to the Firebase project you just created. In the center of the Project overview page, click the Android icon to launch the setup workflow. If you've already added an app to your Firebase project, click Add app to display the platform options.

Add Firebase to your Android App - Register App

Enter your Android package name and your app nickname. Click on Register App.

Add Firebase to your Android App - Download and then add config file

Now click on Download google-services.json and download the google-services.json file. Then click twice on Next and on Continue to console. Move the downloaded file to the /android/app/ directory of your project.

Configure the Push Notification Icon

If no icon is specified, Android uses the application icon, but the push icon should be white pixels on a transparent background. Since the application icon does not usually look like this, it shows a white square or circle. Therefore, it is recommended to provide a separate icon for push notifications.

To do this, add the following line to the android/app/src/main/AndroidManifest.xml file in the application tag:

android/app/src/main/AndroidManifest.xml
<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@mipmap/notification_icon" />

After that you have to add the appropriate icons to the android/app/src/main/res/mipmap-* folders. The icon files should have the name as configured in the AndroidManifest.xml file. In this example they are called notification_icon.png.

Tip

You can create Android Notification Icons using the Android Asset Studio for example.

<meta-data
    android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/colorAccent" />

iOS

Adding push notifications to iOS is unfortunately much more complicated. You also need a paid Apple Developer account.

Add Firebase to your iOS App

Navigate back to the Firebase project you just created. In the center of the project overview page, click the iOS icon to launch the setup workflow. If you've already added an app to your Firebase project, click Add app to display the platform options.

Add Firebase to your Apple App - Register app

Enter your Apple bundle ID and your app nickname. Click on Register App.

Add Firebase to your Apple App - Download config file

Now click on the button Download GoogleService-Info.plist and download the GoogleService-Info.plist file. After that click three times on Next and then on Continue to console. Move the downloaded file to the /ios/App/App/ directory of your project.

Now open XCode by running npx cap open ios in your project. Register the file in your XCode project by dragging it from /ios/App/App/GoogleService-Info.plist into the XCode file explorer into the folder /App/App. If prompted, select to add the config file to all targets.

Add Firebase config file to XCode project

Now it should look like this:

XCode File Explorer

Register the App ID

If you have not yet registered your App Identifier with Apple, log in to your App Store Developer Account and navigate to Identifiers. Add a new App Identifier and make sure that you select the Push Notifications capability.

Register an App ID

Enter the appId from the capacitor.config.ts as bundle ID. Click on Continue and then on Register. Your App Identifier is now registered with Apple.

Create an APNs certificate or key

Next, navigate to the Keys page and click the to add a new key.

Register a New Key

Enter a name and enable Apple Push Notifications service (APNs). Click on Continue and then on Register. Next, download your key and write down the key ID. Usually the Key ID is also included in the filename of the downloaded key.

After download, you need to upload the key in the Messaging Tab of the Firebase Console. Click the Upload button, select your key, enter your Key ID and your Team ID and upload the key to Firebase.

Upload APNs auth key

You can find the Team ID in your Membership details.

Add initialization code​

Add the following to your app's AppDelegate.swift:

ios/App/App/AppDelegate.swift
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
  NotificationCenter.default.post(name: .capacitorDidRegisterForRemoteNotifications, object: deviceToken)
}

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
  NotificationCenter.default.post(name: .capacitorDidFailToRegisterForRemoteNotifications, object: error)
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
  NotificationCenter.default.post(name: Notification.Name.init("didReceiveRemoteNotification"), object: completionHandler, userInfo: userInfo)
}

This makes sure that the plugin is notified about new Apple Push Notification service (APNs) device tokens and incoming push notifications.

Enable Push Notification capabilities

Last but not least you have to enable the Push Notifications and Background Modes capabilities in your XCode project. To do this, open the project using the Capacitor CLI:

npx cap open ios

Select the project App in the File Explorer, click on the corresponding target, switch to the tab Signing & Capabilities and now click on + Capabilities.

Enable Push Notification capabilities in XCode

Search for Push Notifications and add the capability by double clicking on it. Also add the Background Modes capability and select the Remote notifications checkbox.

XCode Signing & Capabilities

Yay, you've done it. The iOS configuration is now ready.

Web

Now we add push notifications to the web platform.

Add Firebase to your Web App

In the center of the project overview page, click the Web+ icon to launch the setup workflow. If you've already added an app to your Firebase project, click Add app to display the platform options.

Add Firebase to your web app - Register app

Enter your app nickname and then click the Register App button.

Add Firebase to your web app - Add Firebase SDK

You now need to add the Firebase configuration to your app. In our Angular app we add the Firebase configuration to the src/environments/environment.ts and src/environments/environment.prod.ts files:

src/environments/environment.ts
export const environment = {
  ...,
  firebase: {
    apiKey: "YOUR_API_KEY",
    authDomain: "YOUR_AUTH_DOMAIN",
    projectId: "YOUR_PROJECT_ID",
    storageBucket: "YOUR_STORAGE_BUCKET",
    messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
    appId: "YOUR_APP_ID"
  },
};

Replace the placeholders with your configuration values. If you use VueJS or React, you have to store the Firebase configuration in a different place.

Next, you need to modify the src/app/app.component.ts as follows:

src/app/app.component.ts
import { Component } from "@angular/core";
import { Capacitor } from "@capacitor/core";
import { IonicModule } from "@ionic/angular";
import { environment } from "src/environments/environment";
import { initializeApp } from "firebase/app";

@Component({
  selector: "app-root",
  templateUrl: "app.component.html",
  styleUrls: ["app.component.scss"],
  standalone: true,
  imports: [IonicModule],
})
export class AppComponent {
  constructor() {
    this.initializeFirebase();
  }

  public async initializeFirebase(): Promise<void> {
    if (Capacitor.isNativePlatform()) {
      return;
    }
    initializeApp(environment.firebase);
  }
}

This makes sure that the Firebase JS SDK is only initialized on the web and not on the native platforms, since on Android and iOS we do not use the Firebase JS SDK but the Firebase Android SDK and the Firebase iOS SDK. These are already initialized using our downloaded configuration files.

Click on Continue to console.

Configure Web Credentials with FCM

FCM Web uses so-called VAPID keys to authorize send requests to supported web push services. You can either generate a new key pair or import an existing pair. We will generate a new key pair in this example. For information on how to import an existing key pair, see Import an existing key pair.

Open the Cloud Messaging Tab in your Firebase project, scroll to the Web configuration section and click Generate key pair.

Generate key pair in Firebase

Copy the generated key into the files src/environments/environment.ts and src/environments/environment.prod.ts. They now look like this (with placeholder):

src/environments/environment.ts
export const environment = {
  ...,
  firebase: {
    apiKey: "YOUR_API_KEY",
    authDomain: "YOUR_AUTH_DOMAIN",
    projectId: "YOUR_PROJECT_ID",
    storageBucket: "YOUR_STORAGE_BUCKET",
    messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
    appId: "YOUR_APP_ID",
    vapidKey: "YOUR_VAPID_KEY"
  },
};

Add the Service Worker

Next, add a service worker to your project by creating an empty file named firebase-messaging-sw.js in the src/ folder.

Add this file to your Assets configuration:

angular.json
"assets": [
  "src/firebase-messaging-sw.js"
]

If you don't want to receive push notifications on the web while your application is in the background, you are now done.

If you want to receive push notifications in the background, add the following content to the firebase-messaging-sw.js file and replace the placeholders with your Firebase configuration:

firebase-messaging-sw.js
importScripts(
  "https://www.gstatic.com/firebasejs/9.7.0/firebase-app-compat.js",
);
importScripts(
  "https://www.gstatic.com/firebasejs/9.7.0/firebase-messaging-compat.js",
);

firebase.initializeApp({
  apiKey: "YOUR_API_KEY",
  authDomain: "YOUR_AUTH_DOMAIN",
  projectId: "YOUR_PROJECT_ID",
  storageBucket: "YOUR_STORAGE_BUCKET",
  messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
  appId: "YOUR_APP_ID",
});
const messaging = firebase.messaging();

More information about receiving push messages on the web can be found at Receive messages in a JavaScript client.

Integrate Push Notifications

Now let's see the Firebase messaging plugin in action. For this, let's first take a look at the following APIs of the plugin:

  • requestPermissions(): Use this method to request permissions to allow push notifications to be displayed.
  • getToken(): This method is needed to request an FCM token. An FCM token is unique and always associated with a specific app installation. Using this token you are able to send push notifications to a specific device. It is common to request the token at app start and send it to the app server. There, the token can be assigned to a user so that individual users can be notified via push notifications using their FCM token. Note that the FCM token can change over time.
  • addListener('notificationReceived', ...): This listener notifies you about incoming push notifications.
  • addListener('notificationActionPerformed', ...): This listener is called when a push notification action is performed. This is the case, for example, when the user opens the notification.

We now use these methods in the HomePage component. Therefore copy the following code into your src/app/homehome.page.ts file:

src/app/homehome.page.ts
import { Component } from "@angular/core";
import {
  FirebaseMessaging,
  GetTokenOptions,
} from "@capacitor-firebase/messaging";
import { Capacitor } from "@capacitor/core";
import { IonicModule } from "@ionic/angular";
import { environment } from "src/environments/environment";

@Component({
  selector: "app-home",
  templateUrl: "home.page.html",
  styleUrls: ["home.page.scss"],
  standalone: true,
  imports: [IonicModule],
})
export class HomePage {
  public token = "";

  constructor() {
    FirebaseMessaging.addListener("notificationReceived", (event) => {
      console.log("notificationReceived: ", { event });
    });
    FirebaseMessaging.addListener("notificationActionPerformed", (event) => {
      console.log("notificationActionPerformed: ", { event });
    });
    if (Capacitor.getPlatform() === "web") {
      navigator.serviceWorker.addEventListener("message", (event: any) => {
        console.log("serviceWorker message: ", { event });
        const notification = new Notification(event.data.notification.title, {
          body: event.data.notification.body,
        });
        notification.onclick = (event) => {
          console.log("notification clicked: ", { event });
        };
      });
    }
  }

  public async requestPermissions(): Promise<void> {
    await FirebaseMessaging.requestPermissions();
  }

  public async getToken(): Promise<void> {
    const options: GetTokenOptions = {
      vapidKey: environment.firebase.vapidKey,
    };
    if (Capacitor.getPlatform() === "web") {
      options.serviceWorkerRegistration =
        await navigator.serviceWorker.register("firebase-messaging-sw.js");
    }
    const { token } = await FirebaseMessaging.getToken(options);
    this.token = token;
  }
}

Lines 27 to 37 contain additional customizations for the web platform. The listener navigator.serviceWorker.addEventListener("message", ...) is called when the browser tab of the application is not focused. Using the Notification Web API, you can show a notification.

Next, we will add the related template. To keep the example as simple as possible, we just create two buttons to manually call the requestPermissions() and getToken() methods. Copy the following code into your src/app/homehome.page.html file:

src/app/homehome.page.html
<ion-header>
  <ion-toolbar>
    <ion-title>Firebase Cloud Messaging</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-card>
    <ion-card-header>
      <ion-card-title>About</ion-card-title>
    </ion-card-header>
    <ion-card-content>
      ⚡️ Capacitor plugin for Firebase Cloud Messaging (FCM).
    </ion-card-content>
  </ion-card>
  <ion-card>
    <ion-card-header>
      <ion-card-title>Demo</ion-card-title>
    </ion-card-header>
    <ion-card-content>
      <ion-item>
        <ion-label position="fixed">Token</ion-label>
        <ion-input type="text" readonly [value]="token"></ion-input>
      </ion-item>
      <ion-button (click)="requestPermissions()"
        >Request Permissions</ion-button
      >
      <ion-button (click)="getToken()">Get Token</ion-button>
    </ion-card-content>
  </ion-card>
</ion-content>

Run the app

Now you can launch your app for the first time:

# Run the web platform
npx ionic serve

# Run the Android platform
npx ionic cap run android

# Run the iOS platform
npx ionic cap run ios

Make sure that the first thing you do is to request the permission using the Request Permissions button.

Request Permissions

Request Permissions

Next, request the FCM token and copy the FCM token to your clipboard so that you can next send a push notification to this device via the Firebase Console.

Send Push Notifications with Firebase

There are several ways to send push notifications with Firebase. You can use the Firebase Console as well as the REST API. Firebase also offers the Firebase Admin SDK for different environments.

Firebase Console

The Firebase Console is the easiest way to test your implementation. For this, navigate to the Messaging page in your Firebase project. If you are visiting the messaging page for the first time, you will see a welcome screen. In this case, click on Create your first campaign, then select Firebase Notification messages and click Create.

Firebase Messaging Onboarding

From here you can directly configure your Push Notification. Enter a notification title and a notification body and click on Send text message.

Firebase Console - Send test message

Paste the FCM token from your clipboard into the input field Add an FCM registration token. Click on the on the right side to confirm the input. After that click on Test and the notification will be sent.

Firebase Console - Test on device

If you did everything correctly, your first notification will arrive. Congratulations!

Firebase REST API

Firebase Cloud Messaging also provides a REST API. Take a look at the official Firebase documentation at Send messages to specific devices to learn how you can send push notifications using it.

Firebase Admin SDK

The Firebase Admin SDK is available on different platforms and is used for the server-side integration of Firebase. Among other things, you can use it to send push notifications. We'll take a quick look at this using Node.js.

Before you can start with the implementation, you first need to generate a service account key. This key grants your application access to your Firebase project. Navigate to Service accounts in the Project settings. Then click Generate new private key and Generate key to download the service account key.

Firebase Console - Generate new private key

Next, create an empty folder and initialize a new npm project:

npm init

First install the Firebase Admin SDK:

npm i firebase-admin

Now create a new file named main.js with the following content:

main.js
import { initializeApp, cert } from "firebase-admin/app";
import { getMessaging } from "firebase-admin/messaging";

initializeApp({
  credential: cert("YOUR_FIREBASE_KEY_PATH"),
});

// This FCM token comes from the Capacitor Firebase Cloud Messaging plugin.
const token = "YOUR_REGISTRATION_TOKEN";

const message = {
  notification: {
    title: "Capacitor Firebase Messaging",
    body: "Hello world!",
  },
  token: token,
};

// Send a message to the device corresponding to the provided FCM token
getMessaging()
  .send(message)
  .then((response) => {
    console.log("Successfully sent message: ", response);
  })
  .catch((error) => {
    console.log("Error sending message: ", error);
  });

Replace the placeholder YOUR_FIREBASE_KEY_PATH with the path to your service account key that you just downloaded from the Firebase Console. Replace the placeholder YOUR_REGISTRATION_TOKEN with the FCM token you get from the Capacitor Firebase Cloud Messaging plugin via the getToken() method.

Now you can run the code and send a push notification using the Firebase Admin SDK:

node main.js

More information about the Firebase Admin SDK can be found at Add the Firebase Admin SDK to your server.

Conclusion

Adding push notifications to an app can be a real challenge depending on the platform. Android makes it easiest for the developer and iOS even requires a paid developer account. Thanks to the Capacitor Firebase Cloud Messaging plugin, once successfully configured, you get a single API for all three platforms. You can find the complete app on GitHub.

Be sure to check out the API Reference to see what else you can do with the Firebase Cloud Messaging plugin. If you have any questions, just create a discussion in the GitHub repository. Make sure you follow Capawesome on X so you don't miss any future updates.