In this tutorial, you're going to learn about Ionic Push, an Ionic service which makes it easy to send push notifications to your users.
Ionic Push allows you to send push notifications to the users of your app. These can be triggered whenever you choose. For example, when it's the user's birthday, you could automatically send them a push notification to greet them.
How It Works
Ionic Push serves as a middle-man between the user's device and the Firebase Cloud Messaging. The first step is for the app to send its device token to the Ionic Push server. This device token serves as an ID which refers to that specific device. Once the server has that token, they can now make a request to the Firebase Cloud Messaging server to actually send a push notification to the device. On each Android device, a Google Play service is running, called the Google Cloud Messaging service. This enables the device to receive push notifications from the Firebase Cloud Messaging platform.
Here's a chart that shows the push notification flow:
What You're Going to Build
You're going to build a simple app which can receive push notifications via Ionic Push. It will also use the Ionic Auth service to log users in. This allows us to try out targeted push notifications which will send the notifications to specific users only. The app will have two pages: the login page and the user page. Users should only be able to receive notifications when they are logged in.
To give you an idea how the notifications would look, here's a screenshot of the notification being received while the app is currently open:
On the other hand, here's what a notification looks like when the app is closed:
Setting Up Push Notifications for Android
In this section, we will configure the Firebase and Ionic cloud services to allow push notifications. Push notifications in Android are mainly handled by the Firebase Cloud Messaging Service. Ionic Push is just a layer on top of this service that makes it easier to work with push notifications in Ionic apps.
Create a Firebase App
The first step is to create a new Firebase project. You can do that by going to the Firebase Console and clicking on the Add project button. You'll see the following form:
Enter the name of the project and click on the Create Project button.
Once the project is created, you will be redirected to the project dashboard. From there, click on the gear icon right beside the Overview tab and select Project Settings.
On the settings page, click on the Cloud Messaging tab. There you will find the Server Key and Sender ID. Take note of these as you will need them later on.
Create an Ionic App
Next, you need to create an Ionic app on the Ionic website. This allows you to work with the Ionic Push service and other Ionic services as well. If you don't already have an Ionic account, you can create one by signing up. Once you've created an account, you'll be redirected to the dashboard where you can create a new app.
Create a Security Profile
Once your app is created, go to Settings >Certificates and click on the New Security Profile button. Enter a descriptive name for the Profile Name and set the Type to Development for now:
Security Profiles serves as a way to securely store the Firebase Cloud Messaging credentials that you got earlier. Once it's created, it will be listed in a table. Click on the Edit button beside the newly created security profile. Then click on the Android tab. Paste the value for the Server Key that you got earlier from the Firebase console into the FCM Server Key field. Finally, click on Save to save the changes.
Bootstrapping a New Ionic App
Create a new Ionic 2 project using the blank template:
ionic start --v2 pushApp blank
Once the project is created, install the phonegap-plugin-push plugin. Supply the Sender ID that you got from the Firebase console earlier:
cordova plugin add phonegap-plugin-push --variable SENDER_ID=YOUR_FCM_SENDER_ID --save
Next, you need to install the Ionic Cloud plugin. This makes it easy to work with Ionic services inside the app:
npm install @ionic/cloud-angular --save
Lastly, you need to update the Ionic config files so that Ionic knows that this specific project should be assigned to the Ionic app that you created earlier. You can do that by copying the app ID in your Ionic app's dashboard page. You can find the app ID right below the name of the app. Once you've copied it, open the .io-config.json
and ionic.config.json
files and paste the value for the app_id
.
Building the App
Now you're ready to build the app. The first thing that you need to do is to fire up the Ionic development server so that you can immediately see the changes as you develop the app:
ionic serve
Once the compilation process is done, access the development URL on your browser.
Add Ionic App and Push Settings
Open the src/app/app.module.ts file and add the settings for the app (core
) and push notifications (push
). The app_id
is the ID of the Ionic app that you created earlier. The sender_id
is the sender ID that you got earlier from the Firebase console. Under the pluginConfig
object, you can optionally set push notification settings. Below we're only setting the sound
and vibrate
settings to true
to tell the hardware that it can play push notification sounds or vibrate if the device is on silent mode. If you want to know more about what configuration options are available, check out the docs on the Push Notification options for Android.
import { CloudSettings, CloudModule } from '@ionic/cloud-angular'; const cloudSettings: CloudSettings = { 'core': { 'app_id': 'YOUR IONIC APP ID', }, 'push': { 'sender_id': 'YOUR FCM SENDER ID', 'pluginConfig': { 'android': { 'sound': true, 'vibrate': true } } } };
Next, let Ionic know that you want to use the cloudSettings
:
imports: [ BrowserModule, IonicModule.forRoot(MyApp), CloudModule.forRoot(cloudSettings) // <-- add this ],
Home Page
The default home page in the blank template will serve as the login page. Open the pages/home/home.html file and add the following:
<ion-header><ion-navbar><ion-title> pushApp</ion-title></ion-navbar></ion-header><ion-content padding><button ion-button full (click)='login();'>Login</button></ion-content>
To keep things simple, we only have a login button instead of a full-blown login form. This means that the credentials that we're going to use for logging in are embedded in the code itself.
Next, open the src/pages/home/home.ts file and add the following:
import { Component } from '@angular/core'; import { NavController, LoadingController, AlertController } from 'ionic-angular'; import { Push, PushToken, Auth, User, UserDetails } from '@ionic/cloud-angular'; import { UserPage } from '../user-page/user-page'; @Component({ selector: 'page-home', templateUrl: 'home.html' }) export class HomePage { constructor(public navCtrl: NavController, public push: Push, public alertCtrl: AlertController, public loadingCtrl: LoadingController, public auth: Auth, public user: User) { if (this.auth.isAuthenticated()) { this.navCtrl.push(UserPage); } } login() { let loader = this.loadingCtrl.create({ content: "Logging in..." }); loader.present(); setTimeout(() => { loader.dismiss(); }, 5000); let details: UserDetails = { 'email': 'YOUR IONIC AUTH USER', 'password': "YOUR IONIC AUTH USER'S PASSWORD" }; this.auth.login('basic', details).then((res) => { this.push.register().then((t: PushToken) => { return this.push.saveToken(t); }).then((t: PushToken) => { loader.dismiss(); this.navCtrl.push(UserPage); }, (err) => { let alert = this.alertCtrl.create({ title: 'Push registration failed', subTitle: 'Something went wrong with push notifications registration. Please try again.', buttons: ['OK'] }); alert.present(); }); }, () => { let alert = this.alertCtrl.create({ title: 'Login Failed', subTitle: 'Invalid Credentials. Please try again.', buttons: ['OK'] }); alert.present(); }); } }
Breaking down the code above, first we import the controllers needed for working with navigation, loaders, and alerts:
import { NavController, LoadingController, AlertController } from 'ionic-angular';
Then import the services needed for working with Push and Auth.
import { Push, PushToken, Auth, User, UserDetails } from '@ionic/cloud-angular';
Once those are added, import the User
page. Comment it out for now as we haven't created that page yet. Don't forget to uncomment this later once the user page is ready.
//import { UserPage } from '../user-page/user-page';
In the constructor, check if the current user is authenticated. Immediately navigate to the user page if they are:
constructor(public navCtrl: NavController, public push: Push, public alertCtrl: AlertController, public loadingCtrl: LoadingController, public auth: Auth, public user: User) { if (this.auth.isAuthenticated()) { this.navCtrl.push(UserPage); } }
For the login
function, show the loader and set it to automatically dismiss after 5 seconds. This way if something goes wrong with the authentication code, the user isn't left with an infinite loading animation:
login() { let loader = this.loadingCtrl.create({ content: "Logging in..." }); loader.present(); setTimeout(() => { loader.dismiss(); }, 5000); }
After that, log the user in with the hard-coded credentials of a user that's already added in your app:
let details: UserDetails = { 'email': 'YOUR IONIC AUTH USER', 'password': "YOUR IONIC AUTH USER'S PASSWORD" }; this.auth.login('basic', details).then((res) => { ... , () => { let alert = this.alertCtrl.create({ title: 'Login Failed', subTitle: 'Invalid Credentials. Please try again.', buttons: ['OK'] }); alert.present(); });
If you don't have an existing user yet, the Ionic dashboard doesn't really allow you to create new users, although you can create additional users once you already have at least one user. So the easiest way to create a new user is to call the signup()
method from the Auth service. Just uncomment the login code above and replace it with the one below. Take note that you can create the user from the browser since the email/password authentication scheme just makes use of HTTP requests.
this.auth.signup(details).then((res) => { console.log('User was created!', res); });
Now that you have a user that you can log in, you can go ahead and remove the signup code and uncomment the login code.
Inside the success callback function for login, you need to call the register()
method from the Push service. This crucial step enables the device to receive push notifications. It makes a request to the Ionic Push service to get a device token. As mentioned in the How It Works section earlier, this device token serves as a unique identifier for the device so that it can receive push notifications.
this.push.register().then((t: PushToken) => { return this.push.saveToken(t); }).then((t: PushToken) => { loader.dismiss(); this.navCtrl.push(UserPage); }, (err) => { let alert = this.alertCtrl.create({ title: 'Push registration failed', subTitle: 'Something went wrong with push notifications registration. Please try again.', buttons: ['OK'] }); alert.present(); });
The great thing about Ionic Push is its integration with Ionic Auth. The reason why we're registering the device tokens right after logging in is because of this integration. When you call the saveToken()
method, it's smart enough to recognize that a user is currently logged in. So it automatically assigns this user to the device. This then allows you to specifically send a push notification to that user.
User Page
The user page is the page which receives push notifications. Create it with the Ionic generate command:
ionic g page userPage
This will create the src/pages/user-page directory with three files in it. Open the user-page.html file and add the following:
<ion-header><ion-navbar hideBackButton="true"><ion-title>User Page</ion-title></ion-navbar></ion-header><ion-content padding><button ion-button full (click)='logout();'>Logout</button></ion-content>
To keep things simple, all we have is a button for logging the user out. The main purpose of this page is to receive and display push notifications only. The logout button is simply added because of the need to log the user out and test if they could still receive notifications after logging out.
Next, open the user-page.ts file and add the following:
import { Component } from '@angular/core'; import { NavController, AlertController } from 'ionic-angular'; import { Push, Auth } from '@ionic/cloud-angular'; @Component({ selector: 'page-user-page', templateUrl: 'user-page.html', }) export class UserPage { constructor(public navCtrl: NavController, public push: Push, public auth: Auth, public alertCtrl: AlertController) { this.push.rx.notification() .subscribe((msg) => { let alert = this.alertCtrl.create({ title: msg.title, subTitle: msg.text, buttons: ['OK'] }); alert.present(); }); } logout() { this.auth.logout(); this.navCtrl.pop(); } }
The code above is pretty self-explanatory, so I'll only go over the part which deals with notifications. The code below handles the notifications. It uses the subscribe()
method to subscribe for any incoming or opened push notification. When I say "opened", it means the user has tapped on the notification in the notifications area. When this happens, the app is launched, and the callback function that you passed to the subscribe()
method gets called. On the other hand, an incoming push notification happens when the app is currently opened. When a push notification is sent, this callback function also gets called. The only difference is that it no longer goes to the notification area.
this.push.rx.notification() .subscribe((msg) => { let alert = this.alertCtrl.create({ title: msg.title, subTitle: msg.text, buttons: ['OK'] }); alert.present(); });
For each notification, the argument passed to the callback function contains the object payload:
In the above code, we're only using the title
and the text
to supply as the content for the alert. We're not limited to just alerts, though—as you can see from the screenshot above, there's this payload
object which stores additional data that you want to pass in to each notification. You can actually use these data to direct what your app is going to do when it receives this kind of notification. In the example above, is_cat
is set to 1
, and we can have the app change its background into a cat picture if it receives this notification. Later on in the Sending Push Notifications section, you'll learn how to customize the payload for each notification.
Running the App on a Device
Now it's time to test out the app on a device. Go ahead and add the platform and build the app for that platform. Here we're using Android:
ionic platform add android ionic build android
Copy the .apk file inside the platforms/android/build/outputs/apk folder to your device and install it.
Solving Build Errors
The first time I tried to run the build
command, I got the following error:
If you got the same error then follow along. If you haven't encountered any errors then you can proceed to the next section.
The problem here is that the SDK components mentioned were not installed, or there might be an important update that needs to be installed. However, the error message is a bit misleading, since it only says that the license agreement needs to be accepted.
So to solve the problem, launch the Android SDK installer and then check the Android Support Repository and Google Repository. After that, click on the Install button and agree to the license agreement to install the components.
Sending Push Notifications
Now that you've installed the app on your device, it's now time to actually send some push notifications. Here are a few scenarios which you can test out:
- when a user isn't currently logged in
- when a user is logged in
- to all users
- to users which match a specific query
- when the app is opened
- when the app is closed
The first step in sending a push notification is to go to your Ionic app dashboard and click on the Push tab. Since this is your first time using the service, you should see the following screen:
Go ahead and click on the Create your first Push button. This will redirect you to the page for creating a push notification. Here you can enter the name of the campaign, title and text of the notification, and any additional data that you want to pass in. Here we're setting is_cat
to 1
.
Next, you can optionally set the push notification options for iOS or Android. Since we're only going to send to Android devices, we only set the options for Android:
The next step is to select the users who will receive the notification. Here you can select All Users if you want to send the notification to all the devices which are registered for push notifications.
If you only want to send to specific users then you can also filter to them:
Take note that the users list is populated from users that are registered via the Auth service.
The final step is to select when to send the notification. Since we're only testing, we can send it immediately. Clicking on the Send This Push button will send the notification to your selected users.
Conclusion and Next Steps
In this tutorial, you've learned about Ionic Push and how it makes push notifications easier to implement. Through the Ionic dashboard, you were able to customize the notifications that you're sending to users. It also allows you to select which users you want to send the notifications to.
This works great if you don't have an existing back end already. But if you already have a back end, you might be asking how you can use Ionic Push with your existing web application. Well, the answer for that is the Ionic HTTP API. This allows you to send an HTTP request from your web server to Ionic's server whenever a specific condition is met. The request that you send will then trigger a push notification to be sent to your users. If you want to learn more, you can check out the docs for the Ionic Push Service.
And while you're here, check out some of our other courses and tutorials on Ionic 2!
- Ionic 2Code Your First Ionic 2 App: A Photo Sharing App
- IonicGet Started With Ionic 2
- IonicHow to Create a Camera App With Ionic 2