Firebase Push Messaging
What is Firebase?
- Build apps fast, without managing infrastructure
- Built on Google infrastructure
- Web and Mobile
- Messaging
- Analytics
- Crash reporting
- Hosting
- Authentication
- Databases
Get started for free!
But be wary
Firebase Costs Increased by 7,000%!
...I used only a few MB of bandwidth — yet their analytics showed 2 GB for that same period!
...they informed me that their profiling tool does not show this SSL overhead
Firebase has finished providing the credits and we have a meeting scheduled next week to dig deeper into usage. They have been great since I got in contact with Alex & Andrew over there. They have definitely resolved this issue in my eyes and I feel they have a better handle on how to handle this moving forward so this doesn’t happen to others!
We told them that we spent the full 25k grant we had just a few days ago and see the chance to apply for the 100k grant on Google Cloud Services. We contacted the team of Google Developers Latam, to tell them what had just happened. They allowed us to apply for the next grant, which google approved,
How we spent 30k USD in Firebase in less than 72 hours
We had reached more than 2 million sessions, more than 20 million pages visited...
We did more than 46 BILLION requests to Firestore
... It was just one bad line of code that was causing that amount of requests
What is Firebase Cloud Messaging?
- Send messages and notifications to users across platforms—Android, iOS, and the web—for free.
- Messages can be sent to single devices, groups of devices, or specific topics or user segments.
- Is a replacement for the older GCM (Google Cloud Messaging)
How does it work?
- Register device and app with Firebase
-
You'll get a token sometimes known as
- Device Token
- Registration Token
- FCM token (previously GCM token)
How does it work?
- Server code that sends a message to an individual person/token, a group or people or a topic
How does it work?
- Server code communicates with Firebase which will then handle the delivery of the messages
What Messages can I send?
- https://firebase.google.com/docs/cloud-messaging/concept-options
-
Notification messages
- sometimes thought of as "display messages." These are handled by the FCM SDK automatically*
-
Data messages
- which are handled by the client app
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification":{
"title":"Portugal vs. Denmark",
"body":"great match!"
}
}
}
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data":{
"Nick" : "Mario",
"body" : "great match!",
"Room" : "PortugalVSDenmark"
}
}
}
What do I need?
- Server side configuration
-
Project ID
- Name of your project needed to make request to Firebase
-
Server key
- Used to send messages
-
Access Token
- Short lived key used to send messages
- Derived from several possibilities e.g. a service account
-
Project ID
What do I need?
- Client Side configuration
-
Token
- Generated dynamically
-
Sender ID
- Identifiers the sender
- Generated in Firebase
-
Token
What do I need?
- Project ID
- Server key
- Sender ID
What do I need?
- Service account to generate Access Token for authentication
To the code!
Local Notifications
Notification.requestPermission(status => {
console.log('Notification permission status:', status, true);
});
Request Permissions
Possible values:
- default
- denied
- granted
Notification.permission
You need permissions to send
You need a service worker to display notifications
navigator.serviceWorker.register('serviceworker.js', {scope: '/'})
.then(function(reg) {
log('Registration succeeded. Scope is ' + reg.scope);
}).catch(function(error) {
log('Registration failed with ' + error);
});
// serviceworker.js
console.log('service worker here');
Local Notifications
payload = {
notification : {
"title": "Push notification",
"body": "No payload so default value here",
"badge": "/logo.png"
}
} },
navigator.serviceWorker.getRegistration().then(function(reg) {
var time = Date.now() - 60*10;
var options = {
body: payload.notification.body,
icon: payload.notification.badge,
"webpush": {
"headers": {
"Urgency": "high"
},
"notification": {
"title": "Web title",
"body": "Web body",
"badge": "/logo.png"
},
}
};
reg.showNotification(payload.notification.title, options);
});
Local Notifications
Tokens
var messaging = firebase.messaging();
function getToken(){
messaging.getToken().then(function(currentToken) {
if (currentToken) {
console.log("We have a token: " + currentToken);
sendTokenToServer(currentToken);
} else {
console.log('No Instance ID token available. Request permission to generate one.');
}
}).catch(function(err) {
console.log('An error occurred while retrieving token. ', err);
});
}
// Callback fired if Instance ID token is updated.
messaging.onTokenRefresh(function() {
messaging.getToken().then(function(refreshedToken) {
console.log('Token refreshed.');
console.log("We have a token: " + refreshedToken);
sendTokenToServer(refreshedToken);
}).catch(function(err) {
console.log('Unable to retrieve refreshed token ', err);
});
});
Get the token. Save it on your server
Handling FCM Notifications
// When web page in foreground in main web page when app is in the foreground
messaging.onMessage(function(payload) {
console.log('Message received. ', payload);
displayNotification(payload);
});
// in service worker firebase-messaging-sw.js
messaging.setBackgroundMessageHandler(function(payload) {
console.log('[firebase-messaging-sw.js] Received background message ', payload);
// Customize notification here
var notificationTitle = 'Background Message Title';
var notificationOptions = {
body: 'Background Message body.',
icon: '/firebase-logo.png'
};
return self.registration.showNotification(notificationTitle,
notificationOptions);
});
Depends if app is in the foreground or background
Get Access Token
const {google} = require('googleapis');
const SCOPES = "https://www.googleapis.com/auth/firebase.messaging";
const SERVICE_ACCOUNT_JSON_FILE = 'SERVICE_ACCOUNT.json'
function getAccessToken() {
return new Promise(function(resolve, reject) {
var key = require(SERVICE_ACCOUNT_JSON_FILE);
var jwtClient = new google.auth.JWT(
key.client_email,null,key.private_key,SCOPES, null
);
jwtClient.authorize(function(err, tokens) {
if (err) {
reject(err);
return;
}
resolve(tokens.access_token);
});
});
}
getAccessToken().then(function(err, tokens){
if (err) {
console.error(err);
return;
}
console.log(tokens);
});
Send Notification to Token
{
"message": {
"token" : "fByerczVlXk:APA91bGKIcOPQOq6ImL....",
"notification": {
"title": "Default Title",
"body": "Default Content"
},
"webpush": {
"headers": {
"Urgency": "high"
},
"notification": {
"title": "Web push title",
"body": "Web push body",
"badge": "/logo.png",
"click_action": "https://google.com"
},
"fcm_options": {
"link": "https://yahoo.com"
}
}
}
}
POST to https://fcm.googleapis.com/v1/projects/{{ProjectName}}/messages:send
Headers
Content-Type: application/json
Authorization: Bearer {{AccessToken}}
Register a device to a topic
POST to https://iid.googleapis.com/iid/v1/{{TOKEN}}/rel/topics/{{TOPIC_NAME}}
Headers
Content-Type: application/json
Authorization: key={{ SERVER_KEY }}
Send Notification to Topic
{
"message": {
"topic": "topic_name1",
"notification": {
"title": "Topic 1",
"body": "Message by topic"
},
"webpush": {
"notification": {
"click_action": "https://yahoo.com"
},
"fcm_options": {
"link": "https://dummypage.com"
}
}
}
}
POST to https://fcm.googleapis.com/v1/projects/{{ProjectName}}/messages:send
Headers
Content-Type: application/json
Authorization: Bearer {{AccessToken}}
Send Notification to Topic 2
{
"message": {
"topic": "topic_name1",
"notification": {
"title": "Topic 1",
"body": "Message by topic"
}
}
}
POST to https://fcm.googleapis.com/fcm/send
Headers
Content-Type: application/json
Authorization: key= {{ SERVER_KEY }}
Remove Token Registration
DELETE to https://iid.googleapis.com/v1/web/iid/{{TOKEN}}
Headers
Content-Type: application/json
Authorization: key= {{ SERVER_KEY }}
Summary
- So many docs (with repeated content)
- Some parts not needed? e.g.
usePublicVapidKey
- So many different authentications
- Duplicate ways of sending messages e.g. 2 ways to send by topic
- Some things don't work?!?!?
- webpush link / click_action
Firebase Push Messaging
By Timothy Lim
Firebase Push Messaging
- 1,225