Skip to Content
Technical Articles

SAPUI5 Applications with Firebase Cloud Messaging

Hi there!

Nice to see you back, means you made it through to authentication part. Awesome!

If you didn’t, feel free to continue reading this blog or go 1 step back and check out the authentication part.

SAPUI5 FIREBASE BLOG SERIES:

Create SAPUI5 Applications with Google Firebase
SAPUI5 Applications with Firebase Anonymous Authentication
SAPUI5 Applications with Firebase Cloud Messaging (this blog)

Like I mentioned in the previous blog we added the authentication part.

Now we can ask logged in users for permission to send notifications to their browser.

Now we want to receive notifications about shipments. We want to receive the notifications when we are focused on the application, but also when we are working in other tabs in the browser.

Actually we are all wandering how to do this. So let me stop explaining why why why, because we all know our own requirements on when to use them. In this case I only can say one thing….

 

Let’s get started!

We will be going through a few steps by writing some code and adding some files.

Some parts could be a little bit hard to understand, but don’t worry. Everything you need to know is explained in detail:

 

Alright all information sharing set and good to go!

 

1. Add the Firebase Cloud Messaging JS SDK

This messaging SDK will be added in our index.html file. In here we also imported our Firebase-app, Firestore and Authentication SDK’s.

Add the following messaging sdk:

<!-- Add the Firebase Messaging JS SDK -->
<script src="https://www.gstatic.com/firebasejs/6.2.0/firebase-messaging.js"></script>

 

 

2. Add the Google Cloud Messaging Sender id

We add this sender id right into our manifest.json file at the top. (you can use this id)

"gcm_sender_id": "103953800507",

This id can be found on Set up a JavaScript Firebase Cloud Messaging client app.

 

 

3. Create the firebase-messaging-sw.js file

This is a service worker file that will be searched for by the messaging service.

Place it in the root of your folder structure:

In here we will do a few things:

  • Import the required firebase-app and messaging service for the service worker.
  • Add our firebase-config again and initialize it.
  • Create a FCM reference.

Your firebase-messaging-sw-js file should look like this:

// Give the service worker access to Firebase Messaging.
// Note that you can only use Firebase Messaging here, other Firebase libraries
// are not available in the service worker.
importScripts('https://www.gstatic.com/firebasejs/6.2.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/6.2.0/firebase-messaging.js');

const firebaseConfig = {
	apiKey: "YOUR-API-KEY",
	authDomain: "YOUR-AUTH-DOMAIN",
	databaseURL: "YOUR-DATABASE-URL,
	projectId: "YOUR-PROJECT-ID",
	storageBucket: "YOUR-STORAGE-BUCKET,
	messagingSenderId: "YOUR-MESSAGE-SENDER-ID",
	appId: "YOUR-APP-ID"
};

firebase.initializeApp(firebaseConfig);

//FCM Reference
const messaging = firebase.messaging();

Now this file has been created and the firebase config is initialized we are all set and done so far.

 

 

4. Set the Messaging Reference in the Firebase.js file

Like we added the Firestore and Authentication reference before, we now want to add the messaging reference in the Firebase.js file. We do this likes so:

// Create a FCM reference
const messaging = firebase.messaging();
			
// Firebase services object
const oFirebase = {
	firestore: firestore,
	fireAuth: fireAuth,
	fcm: messaging
};

Now we can access our messaging service through our firebaseModel.

 

 

5. Request permission to send Notifications

We ask this permission in the Component.js file. This in our earlier created onAuthStateChanged observer.

We do this in the onAuthChanged obserever when we are logged in. So only logged in users can give us the permission and therefore we will only send shipment related notifications to logged in users.

The first thing we need to do is bind ‘this’ to our observer:

firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    // User is signed in.
    var isAnonymous = user.isAnonymous;
    var uid = user.uid;
    console.log("User: ", user);
  } else {
    // User is signed out.
  }
}.bind(this));

This because we will use the this reference in our observer.

 

The next thing we want to do is request the permission.

  • Get the messaging reference from the ‘firebaseModel’ by its property. (this is where and why we bound ‘this’ to our observer.
  • We ask the permission and log that we have permission if we have permission.
  • If we have permission we will get a FCM messaging token and logged it to the console.

Like this (inside the if(user) statement):

// CLOUD MESSAGING FCM
// Since we are logged in now we will ask the user permission to send notifications
// Create a FCM reference
const messaging = this.getModel("firebase").getProperty("/fcm");

//FCM ask permission
messaging.requestPermission().then(function () {
	console.log("Have permission");
	return messaging.getToken();
}).then(function (token) {
	console.log(token);
}).catch(function (err) {
	console.log("Error occured");
});

 

 

6. Receive Notifications in the Foreground

So now we have our token, we can do whatever we want with a message we receive, by adding the onMessage function. Still in the Component.js file under the requestPermission function.

This function will handle notifications on the foreground. So when we are focused on the tab with our app. In some cases you do not want to show notifications when in foreground or handle this incoming message in a different way. Whatever you want to do with it, this happens in the onMessage function. So the foreground handler.

 

In this case we will just show the notification anyway.

  • Parse the received JSON payload.
  • Log the received message to the console.
  • Get the title and the notifications options
  • Create a new Notification object with the title and options attributes.
  • Return the notification.

This by adding the following code:

// Show message in foreground (if desired)
messaging.onMessage(function (payload) {
	console.log("Message received. ", payload);
	var notification = JSON.parse(payload.data.notification);
	const notificationTitle =notification.title;
	const notificationOptions = {
		body: notification.body,
		icon: notification.icon,
	};
	var notification = new Notification(notificationTitle, notificationOptions);
	return notification;
});

When we now send notifications the message will be showed on the foreground.

 

So your full Component.js file init function should look like this:

init: function () {
	// call the base component's init function
	UIComponent.prototype.init.apply(this, arguments);

	// enable routing
	this.getRouter().initialize();

	// set the device model
	this.setModel(models.createDeviceModel(), "device");

	// Import Firebase in the sap.ui.define
	// set the firebase model by calling the initializeFirebase function in the Firebase.js file
	this.setModel(Firebase.initializeFirebase(), "firebase");

	// AUTHENTICATION
	// Create a Fireauth reference
	const fireAuth = this.getModel("firebase").getProperty("/fireAuth");

	// Login the user anonymously
	fireAuth.signInAnonymously().catch(function (error) {
		// Handle Errors here.
		var errorCode = error.code;
		var errorMessage = error.message;
	});

	// If the signInAnonymously method completes without error, the observer registered in the onAuthStateChanged 
	// will trigger and you can get the anonymous user's account data from the User object:
	fireAuth.onAuthStateChanged(function (user) {
		if (user) {
			// Example of accessible properties 
			var isAnonymous = user.isAnonymous;
			var uid = user.uid;
			console.log("User: ", user);

			// CLOUD MESSAGING FCM
			// Since we are logged in now we will ask the user permission to send notifications
			// Create a FCM reference
			const messaging = this.getModel("firebase").getProperty("/fcm");

			//FCM ask permission
			messaging.requestPermission().then(function () {
				console.log("Have permission");
				return messaging.getToken();
			}).then(function (token) {
				console.log(token);
			}).catch(function (err) {
				console.log("Error occured");
			});

			// Show message in foreground (if desired)
			messaging.onMessage(function (payload) {
				console.log("Message received. ", payload);
				var notification = JSON.parse(payload.data.notification);
				const notificationTitle =notification.title;
				const notificationOptions = {
					body: notification.body,
					icon: notification.icon,
				};
				var notification = new Notification(notificationTitle, notificationOptions);
				return notification;
			});
		} else {
			// User is signed out.
		}
	}.bind(this));

}

 

 

 

7. Receive Notifications in the Background

To receive notifications in the background (while not focused in the app on the current tab, or with the browser minimized) we need to update the firebase-messaging-sw-js file.

This by adding setBackgroundMessageHandler function.

This function handles obviously the in background received messages.

  • We log the notification to the console.
  • We parse the content.
  • set the title and the options.
  • Return the Notification by calling the self.registartion.showNotification. (default browser function to show notifications)
// Enable background messaging handler
messaging.setBackgroundMessageHandler(function (payload) {
	console.log("Message received in background. ", payload);
	
	// Retrieve data from the notification
	var notification = JSON.parse(payload.data.notification);
	const notificationTitle = notification.title;
	const notificationOptions = {
		body: notification.body,
		icon: "/webapp/" + notification.icon
	};

	// Show the notification with the params
	return self.registration.showNotification(notificationTitle,
		notificationOptions);
});

As you can see for the icon property we added a prefix. This prefix is used to build our path to the image that we want to show in our notification.

Later when we send a message we will add the image name to our payload.

But we need to add the image id to our webapp folder.

So place it right here:

 

 

8. Get you Server Token

To send a notification you will need a server token, this server token can be found in the Firebase console. This under project settings -> Cloud Messaging -> Server token.

 

 

9. Get your Receiver Token

Next you need a receiver, this receiver token is the token logged when you requested one in the Component.js file. Remember the code:

//FCM ask permission
messaging.requestPermission().then(function () {
	console.log("Have permission");
	return messaging.getToken();
}).then(function (token) {
	console.log(token);
}).catch(function (err) {
	console.log("Error occured");
});

So this token is the token which you send to.

So let’s get this token. Time to run the app.

When you run the app the app will ask your permission to send notifications. We will allow of course.

Next we open the console we will see we have permission to send notifications and our receiver token is logged.

(I hid a part of the key, it is a longer key than what you see)

 

 

10. Send a Notification

Sending notifications can be done in multiple ways.

You can send them for example by using:

  • CURL command
  • Postman

Here is a CURL example:

  • Change the  YOUR-SERVER-TOKEN to your server token from the Firebase console.
  • Change the YOUR-RECEIVER-TOKEN to your receiver token from the Chrome console.
  • Set the name of the image in the icon to the name of the image you uploaded in you webapp folder.
curl --header "Authorization: key=YOUR-SERVER-TOKEN" --header Content-Type:"application/json" -d "{\"to\":\"YOUR-RECEIVER-TOKEN\",\"data\":{\"notification\": {\"title\":\"Shipment lost\",\"body\":\"A shipment of Brussels just got lost.\",\"icon\":\"shipment.png\"}}}" https://fcm.googleapis.com/fcm/send

You can also add the notification to the root JSON structure. But then the messages will only be displayed in the onMessage function. So it will always think it should be handled as a foreground message. By adding the data property it knows when the app is in the background, this backgroundhandler needs to take over. But then the value of the data property is handled as a string. That’s why we parse it.

 

Run the CURL command in a terminal and see the notifications arrive in the foreground and background! 🙂

FOREGROUND NOTIFICATION RECEIVED:

BACKGROUND NOTIFICATION RECEIVED:

 

 

Demo action time! 

 

Recap time, what did we learn? 

In this blog we added the Firebase Cloud Messaging Service to our UI5 Application.

So here are some key takeaways:

  1. We need to add the the messaging service to our app.
  2. A service worker file called “firebase-messaging-sw.js” needs to be created.
  3. Receiving Notifications in the foreground and background need to be handled in a different way.
  4. How to send Notifications to clients.

 

Thanks for reading my blog about “SAPUI5 Applications with Firebase Cloud Messaging“.

I hope you found it interesting and it can serve your requirements!

Kind regards,

Dries

 

Be the first to leave a comment
You must be Logged on to comment or reply to a post.