Skip to content

Instantly share code, notes, and snippets.

@loicginoux
Last active January 12, 2024 07:14
Show Gist options
  • Star 28 You must be signed in to star a gist
  • Fork 12 You must be signed in to fork a gist
  • Save loicginoux/203a378560bd7ba56116e2da2526fa1f to your computer and use it in GitHub Desktop.
Save loicginoux/203a378560bd7ba56116e2da2526fa1f to your computer and use it in GitHub Desktop.
Adding FCM to an html page to receive notifications and sending then via FCM ruby gem. (edit: HTTPS needed!)
// [START initialize_firebase_in_sw]
// 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/3.5.2/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.5.2/firebase-messaging.js');
// Initialize the Firebase app in the service worker by passing in the
// messagingSenderId.
firebase.initializeApp({
'messagingSenderId': '40911931240'
});
// Retrieve an instance of Firebase Messaging so that it can handle background
// messages.
const messaging = firebase.messaging();
// [END initialize_firebase_in_sw]
// If you would like to customize notifications that are received in the
// background (Web app is closed or not in browser focus) then you should
// implement this optional method.
// [START background_handler]
messaging.setBackgroundMessageHandler(function(payload) {
console.log('[firebase-messaging-sw.js] Received background message ', payload);
// Customize notification here
const notificationTitle = 'Background Message Title';
const notificationOptions = {
body: 'Background Message body.'
};
return self.registration.showNotification(notificationTitle,
notificationOptions);
});
// [END background_handler]
<head>
<link rel="manifest" href="<%= asset_path 'manifest.json' %>">
<script src="https://www.gstatic.com/firebasejs/3.7.1/firebase.js"></script>
<script>
var config = {
apiKey: "<YOUR_API_KEY>",
authDomain: "<FCM_APP>.firebaseapp.com",
databaseURL: "https://<FCM_APP>.firebaseio.com",
storageBucket: "<FCM_APP>.appspot.com",
messagingSenderId: "<MESSAGE_SENDER_ID>"
};
firebase.initializeApp(config);
</script>
</head>
// [START get_messaging_object]
// Retrieve Firebase Messaging object.
const messaging = firebase.messaging();
// [END get_messaging_object]
// IDs of divs that display Instance ID token UI or request permission UI.
const tokenDivId = 'token_div';
const permissionDivId = 'permission_div';
// [START refresh_token]
// Callback fired if Instance ID token is updated.
messaging.onTokenRefresh(function() {
messaging.getToken()
.then(function(refreshedToken) {
console.log('Token refreshed.');
// Indicate that the new Instance ID token has not yet been sent to the
// app server.
setTokenSentToServer(false);
// Send Instance ID token to app server.
sendTokenToServer(refreshedToken);
// [START_EXCLUDE]
// Display new Instance ID token and clear UI of all previous messages.
resetUI();
// [END_EXCLUDE]
})
.catch(function(err) {
console.log('Unable to retrieve refreshed token ', err);
showToken('Unable to retrieve refreshed token ', err);
});
});
// [END refresh_token]
// [START receive_message]
// Handle incoming messages. Called when:
// - a message is received while the app has focus
// - the user clicks on an app notification created by a sevice worker
// `messaging.setBackgroundMessageHandler` handler.
messaging.onMessage(function(payload) {
console.log("Message received. ", payload);
// [START_EXCLUDE]
// Update the UI to include the received message.
appendMessage(payload);
// [END_EXCLUDE]
});
// [END receive_message]
function resetUI() {
clearMessages();
showToken('loading...');
// [START get_token]
// Get Instance ID token. Initially this makes a network call, once retrieved
// subsequent calls to getToken will return from cache.
messaging.getToken()
.then(function(currentToken) {
if (currentToken) {
sendTokenToServer(currentToken);
updateUIForPushEnabled(currentToken);
} else {
// Show permission request.
console.log('No Instance ID token available. Request permission to generate one.');
requestPermission()
// Show permission UI.
updateUIForPushPermissionRequired();
setTokenSentToServer(false);
}
})
.catch(function(err) {
console.log('An error occurred while retrieving token. ', err);
showToken('Error retrieving Instance ID token. ', err);
setTokenSentToServer(false);
});
}
// [END get_token]
function showToken(currentToken) {
// Show token in console and UI.
console.log("showToken: ", currentToken)
// var tokenElement = document.querySelector('#token');
// tokenElement.textContent = currentToken;
}
// Send the Instance ID token your application server, so that it can:
// - send messages back to this app
// - subscribe/unsubscribe the token from topics
function sendTokenToServer(currentToken) {
if (!isTokenSentToServer()) {
console.log('Sending token to server...');
// TODO(developer): Send the current token to your server.
setTokenSentToServer(true);
} else {
console.log('Token already sent to server so won\'t send it again ' +
'unless it changes');
}
}
function isTokenSentToServer() {
if (window.localStorage.getItem('sentToServer') == 1) {
return true;
}
return false;
}
function setTokenSentToServer(sent) {
window.localStorage.setItem('sentToServer', sent ? 1 : 0);
}
function showHideDiv(divId, show) {
// const div = document.querySelector('#' + divId);
if (show) {
console.log("should show div:", divId)
// div.style = "display: visible";
} else {
console.log("should hide div:", divId)
// div.style = "display: none";
}
}
function requestPermission() {
console.log('Requesting permission...');
// [START request_permission]
messaging.requestPermission()
.then(function() {
console.log('Notification permission granted.');
// TODO(developer): Retrieve an Instance ID token for use with FCM.
// [START_EXCLUDE]
// In many cases once an app has been granted notification permission, it
// should update its UI reflecting this.
resetUI();
// [END_EXCLUDE]
})
.catch(function(err) {
console.log('Unable to get permission to notify.', err);
});
// [END request_permission]
}
function deleteToken() {
// Delete Instance ID token.
// [START delete_token]
messaging.getToken()
.then(function(currentToken) {
messaging.deleteToken(currentToken)
.then(function() {
console.log('Token deleted.');
setTokenSentToServer(false);
// [START_EXCLUDE]
// Once token is deleted update UI.
resetUI();
// [END_EXCLUDE]
})
.catch(function(err) {
console.log('Unable to delete token. ', err);
});
// [END delete_token]
})
.catch(function(err) {
console.log('Error retrieving Instance ID token. ', err);
showToken('Error retrieving Instance ID token. ', err);
});
}
// Add a message to the messages element.
function appendMessage(payload) {
console.log("appendMessage", payload)
// const messagesElement = document.querySelector('#messages');
// const dataHeaderELement = document.createElement('h5');
// const dataElement = document.createElement('pre');
// dataElement.style = 'overflow-x:hidden;'
// dataHeaderELement.textContent = 'Received message:';
// dataElement.textContent = JSON.stringify(payload, null, 2);
// messagesElement.appendChild(dataHeaderELement);
// messagesElement.appendChild(dataElement);
}
// Clear the messages element of all children.
function clearMessages() {
console.log("clearMessages.")
// const messagesElement = document.querySelector('#messages');
// while (messagesElement.hasChildNodes()) {
// messagesElement.removeChild(messagesElement.lastChild);
// }
}
function updateUIForPushEnabled(currentToken) {
showHideDiv(tokenDivId, true);
showHideDiv(permissionDivId, false);
showToken(currentToken);
}
function updateUIForPushPermissionRequired() {
showHideDiv(tokenDivId, false);
showHideDiv(permissionDivId, true);
}
resetUI();
{
"//": "Some browsers will use this to enable push notifications.",
"//": "It is the same for all projects, this is not your project's sender ID",
"gcm_sender_id": "<MESSAGE_SENDER_ID>"
}
require 'fcm'
api_key = "<API_KEY>"
registration_tokens = [<REGISTRATION_TOKEN_FROM_BROWSER>]
fcm = FCM.new(api_key)
# options = {data: {score: "123"}}
options = {
notification: {
title: "Portugal vs. Denmark",
body: "5 to 1",
icon: "firebase-logo.png",
click_action: "http://localhost:8081"
}
}
response = fcm.send(registration_tokens, options)
@cdsaenz
Copy link

cdsaenz commented Aug 18, 2018

Thanks a lot! This is the ONLY fcm messaging example I could make work so far, after days testing! Now gotta dig into into it to see how it works (and why, while others don't)

@bradymholt
Copy link

Thank you - very helpful!

@darshan78261992
Copy link

darshan78261992 commented Feb 11, 2019

Can we add multiple action button like below
actions :[{}]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment