Using Push Notifications with Firebase in an Ionic + Angular App
Web Framework: Angular Platforms: iOS, Android
One of the most common features provided by application developers to their users is push notifications. In this tutorial, we'll walk through all the steps needed to get Firebase Cloud Messaging working on iOS and Android.
For the purposes of registering and monitoring for push notifications from Firebase, we'll make use of the Push Notification API for Capacitor in an Ionic + Angular application.
Required Dependencies
Building and deploying iOS and Android applications using Capacitor requires a bit of setup. Please follow the instructions to install the necessary Capacitor dependencies here before continuing.
To test push notifications on iOS, Apple requires that you have a paid Apple Developer account and a physical iOS device.
If you are running into issues or your console throws warnings about outdated or deprecated packages, make sure that you're on the latest stable versions of Node, Android Studio, and Xcode.
Also, we're using Firebase for push notifications, so if you're using other Cordova plugins that use the Firebase SDK make sure they're using the latest versions.
Prepare an Ionic Capacitor App
If you have an existing Ionic app, skip this section. If not, let's create an Ionic app first.
In your preferred terminal, install the latest version of the Ionic CLI:
npm install -g @ionic/cli
Next, let's use the CLI to create a new Ionic Angular app based on the blank starter project and call it capApp:
ionic start capApp blank --type=angular
On the prompt asking to integrate your new app with Capacitor, type y
and press enter. That will add Capacitor and the Capacitor CLI to our new application.
Once the application has been created successfully, switch to the newly created project directory:
cd capApp/
Finish up by running npx cap init
, which will allow us to fill out our app information.
npx cap init
? App name: CapApp
? App Package ID: com.mydomain.myappname
Building the App & Adding Platforms
Before adding any native platforms to this project, the app must be built at least once. A web build creates the web assets directory that Capacitor needs (www
folder in Ionic Angular projects).
ionic build
Next, let's add the iOS and Android platforms to our app.
npx cap add ios
npx cap add android
Upon running these commands, both android
and ios
folders at the root of the project are created. These are entirely separate native project artifacts that should be considered part of your Ionic app (i.e., check them into source control).
Using the Capacitor Push Notification API
Before we get to Firebase, we'll need to ensure that our application can register for push notifications by making use of the Capacitor Push Notification API. We'll also add an alert
(you could use console.log
statements instead) to show us the payload for a notification when it arrives and the app is open on our device.
In your app, head to the home.page.ts
file and add an import
statement and a const
to make use of the Capacitor Push API:
import {
Plugins,
PushNotification,
PushNotificationToken,
PushNotificationActionPerformed,
} from '@capacitor/core';
const { PushNotifications } = Plugins;
Then, add the ngOnInit()
method with some API methods to register and monitor for push notifications. We will also add an alert()
a few of the events to monitor what is happening:
export class HomePage implements OnInit {
ngOnInit() {
console.log('Initializing HomePage');
// Request permission to use push notifications
// iOS will prompt user and return if they granted permission or not
// Android will just grant without prompting
PushNotifications.requestPermission().then( result => {
if (result.granted) {
// Register with Apple / Google to receive push via APNS/FCM
PushNotifications.register();
} else {
// Show some error
}
});
// On success, we should be able to receive notifications
PushNotifications.addListener('registration',
(token: PushNotificationToken) => {
alert('Push registration success, token: ' + token.value);
}
);
// Some issue with our setup and push will not work
PushNotifications.addListener('registrationError',
(error: any) => {
alert('Error on registration: ' + JSON.stringify(error));
}
);
// Show us the notification payload if the app is open on our device
PushNotifications.addListener('pushNotificationReceived',
(notification: PushNotification) => {
alert('Push received: ' + JSON.stringify(notification));
}
);
// Method called when tapping on a notification
PushNotifications.addListener('pushNotificationActionPerformed',
(notification: PushNotificationActionPerformed) => {
alert('Push action performed: ' + JSON.stringify(notification));
}
);
}
Here is the full implementation of home.page.ts
:
import { Component, OnInit } from '@angular/core';
import {
Plugins,
PushNotification,
PushNotificationToken,
PushNotificationActionPerformed,
} from '@capacitor/core';
const { PushNotifications } = Plugins;
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage implements OnInit {
ngOnInit() {
console.log('Initializing HomePage');
// Request permission to use push notifications
// iOS will prompt user and return if they granted permission or not
// Android will just grant without prompting
PushNotifications.requestPermission().then(result => {
if (result.granted) {
// Register with Apple / Google to receive push via APNS/FCM
PushNotifications.register();
} else {
// Show some error
}
});
PushNotifications.addListener(
'registration',
(token: PushNotificationToken) => {
alert('Push registration success, token: ' + token.value);
},
);
PushNotifications.addListener('registrationError', (error: any) => {
alert('Error on registration: ' + JSON.stringify(error));
});
PushNotifications.addListener(
'pushNotificationReceived',
(notification: PushNotification) => {
alert('Push received: ' + JSON.stringify(notification));
},
);
PushNotifications.addListener(
'pushNotificationActionPerformed',
(notification: PushNotificationActionPerformed) => {
alert('Push action performed: ' + JSON.stringify(notification));
},
);
}
}
After this, you'll want to generate a new build and let Capacitor know about the changes. You can do that with:
ionic build
npx cap copy
Creating a Project for your App on Firebase
Before we can connect Firebase Cloud Messaging to your application and send push notifications, you'll need to start a project in Firebase.
Go to the Firebase Console and click the Add project button.
Name the project, accept the Firebase ToS and click Create project to continue. A Project ID should be automatically generated for you.
Android
Integrating Firebase with the Android app
This section more-or-less mirrors the setting up Firebase using the Firebase console documentation. See below for specific Capacitor-related notes.
Go to the Project Overview page for your Firebase project and at the top, click on the Android icon to add a new android application.
The next screen will ask you for some information about your application.
- Your Android package name should match the appId from your
capacitor.config.json
file - We used
com.mydomain.myappname
for this Capacitor app ID, so that is what we'll use for this entry. - Nickname and Debug Signing Certificate are optional
Then click the Register app button.
Download and Use the google-services.json
file
The next prompt will ask you to download a google-services.json
file. This file contains the information your Capacitor app needs to connect to Firebase from Android.
Download the google-services.json
file to your local machine. Then move the file into your Capacitor Android project directory, specifically under android/app/
.
We don't need to add any dependencies to our project because Capacitor projects automatically include a version of firebase-messaging
in it's build.gradle
file.
iOS
Prerequisites
iOS push notifications are significantly more complicated to set up than Android. You must have a paid Apple Developer account and take care of the following items prior to being able to test push notifications with your iOS application:
- Setup the proper Development or Production certificates & provisioning profiles for your iOS application in the Apple Developer Portal
- Create an APNS certificate or key for either Development or Production in the Apple Developer Portal
- Ensure Push Notification capabilities have been enabled in your application in Xcode
- Have a physical iOS device as per the guidelines in the Dependencies documentation
Integrating Firebase with our native iOS app
This part is very similar to the Android section above, with a few key differences.
First, go to the Project Overview page for your Firebase project. If you've been following this guide, you'll already have an Android application listed at the top of the page.
To add iOS to your Firebase project, click the Add App button and select the iOS platform.
The next screen will ask you for some information about your application.
- Your iOS bundle ID should match the appId from your
capacitor.config.json
file - We used
com.mydomain.myappname
for this Capacitor app ID, so that is what we'll use for this entry. - App Nickname and App Store ID are optional
Then click the Register app button.
Add the GoogleService-Info.plist
file to your iOS app
Note: This is not the same file used for your Android app.
Download the GoogleService-Info.plist
provided to your local machine.
You'll then want to open Xcode...
npx cap open ios
... and move the .plist
file into your Xcode project as instructed by Firebase, ensuring to add it to all targets.
Add the Firebase SDK via CocoaPods
The Push Notification API on iOS makes use of CocoaPods - an iOS dependency management system - and we need to tell CocoaPods to make use of Firebase.
To do this, we need to modify the Podfile
, which can be found in Xcode under Pods
:
We need to add Firebase to the CocoaPods provided for our App target. To do that, add pod 'FirebaseCore'
and pod 'Firebase/Messaging'
to your target 'App'
section, like so:
target 'App' do
capacitor_pods
# Add your Pods here
pod 'FirebaseCore', '7.11.0' # Add this line
pod 'Firebase/Messaging', '7.11.0' # Add this line
end
Your Podfile
should look something like this:
platform :ios, '11.0'
use_frameworks!
# workaround to avoid Xcode caching of Pods that requires
# Product -> Clean Build Folder after new Cordova plugins installed
# Requires CocoaPods 1.6 or newer
install! 'cocoapods', :disable_input_output_paths => true
def capacitor_pods
# Automatic Capacitor Pod dependencies, do not delete
pod 'Capacitor', :path => '../../node_modules/@capacitor/ios'
pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios'
# Do not delete
end
target 'App' do
capacitor_pods
# Add your Pods here
pod 'FirebaseCore', '7.11.0'
pod 'Firebase/Messaging', '7.11.0'
end
Update the Project
Now we'll need to ensure that our iOS project is updated with the proper Firebase CocoaPod installed.
Note: This part can take a while as CocoaPods needs to download all the appropriate files/dependencies.
npx cap update ios
Add Initialization Code
To connect to Firebase when your iOS app starts up, you need to add the following to your AppDelegate.swift
file.
First, add an import
at the top of the file:
import FirebaseCore