This tutorial is about Firebase Cloud Messaging, which is one of the Firebase Products
Tutorials :
https://firebase.google.com/docs/cloud-messaging/js/client?hl=en&authuser=0
Steps:
-
Get Credentials
Firebase Console URL : https://console.firebase.google.com/- Create project
- Create App
- Get Required Credentials
Go to Firebase Console → Project Settings → General → Your apps → Web app (or create one).
Frontend :- firebaseConfig : for
initializeApp
Project Settings → Genenal & Scroll down and copy from sample code. - vapidKey : for
getToken
Project Settings → Cloud Messanging → Web Push Certificates → Key pair - fcmToken: received in
getToken
. Use this to sendtest notification
from console. ClickSend test Message
. Add fcmToken
Backend : - $serviceAccountPath : for
getAccessToken
Project Settings → Service accounts & ClickGenerate new private key
- $projectId : to use in
$url = 'https://fcm.googleapis.com/v1/projects/' . $projectId . '/messages:send';
Project Settings → Genenal
- firebaseConfig : for
- Add accounts in Google console. This is optional.
Project Settings → Service accounts & ClickManage Service account permissions
Service worker js
to handle notification in backgroundfirebase-messaging-sw.js
. ie save asC:\wamp64\www\firebase-messaging-sw.js
Frontend script
to subscribe http://localhost/pjtsreehp/easelex/OSOLMVC/tests/firebase/topic/copilotRecieveMessage4Topic.js- Send Test message from Console
- install dependencies with composer
composer --with-all-dependencies require kreait/firebase-php
- Backend script to send mesage with
fcmToken
. test with php,min PHP 8.2
Notifications to Topics
Tutorials :
https://firebase.google.com/docs/cloud-messaging/js/send-multiple
https://firebase.google.com/docs/cloud-messaging/js/topic-messaging
- Backend script to subscribe to topic http://localhost/pjtsreehp/easelex/OSOLMVC/tests/firebase/topic/subscribe_to_topic2.php
- Frontend page to subscribe to topic http://localhost/pjtsreehp/easelex/OSOLMVC/tests/firebase/topic/copilotRecieveMessage4Topic.php
- Backend Script to send push message http://localhost/pjtsreehp/easelex/OSOLMVC/tests/firebase/topic/copilotSendMessage2Topics.php
Codes
- Service Worker js
- Frontend JS to register and receive message
- HTML to receive FCM
- Backend script to send message to registered devices
- Backend PHP script to subscribe to topic
- Frontend JS to subscribe to topic
- Alternate method using OAuthToken from server using getAccessToken($serviceAccountPath)
- Backend PHP to send push message to topic
- Send message with Kreait
Service worker js
firebase-messaging-sw.js
FCM requires a firebase-messaging-sw.js file. Unless you already have a firebase-messaging-sw.js file, create an empty file with that name and place it in the root of your domain before retrieving a token. You can add meaningful content to the file later in the client setup process.
FirebaseError: Messaging: We are unable to register the default service worker. ServiceWorker script at http://localhost/firebase-messaging-sw.js for scope http://localhost/firebase-cloud-messaging-push-scope encountered an error during installation. (messaging/failed-service-worker-registration).
/*
FCM requires a firebase-messaging-sw.js file. Unless you already have a firebase-messaging-sw.js file, create an empty file with that name and place it in the root of your domain before retrieving a token. You can add meaningful content to the file later in the client setup process.
FirebaseError: Messaging: We are unable to register the default service worker. ServiceWorker script at http://localhost/firebase-messaging-sw.js for scope http://localhost/firebase-cloud-messaging-push-scope encountered an error during installation. (messaging/failed-service-worker-registration).
*/
importScripts("https://www.gstatic.com/firebasejs/10.11.1/firebase-app-compat.js");
importScripts("https://www.gstatic.com/firebasejs/10.11.1/firebase-messaging-compat.js");
const firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_AUTH_DOMAIN",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_STORAGE_BUCKET",
messagingSenderId: "YOUR_SENDER_ID",
appId: "YOUR_APP_ID"
};
firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();
messaging.onBackgroundMessage((payload) => {
console.log("Background message:", payload);
self.registration.showNotification(payload.notification.title, {
body: "BG \r\n" + payload.notification.body ,
});
});
Frontend JS to register and receive message
Back to Codes
register2FCMAndReceiveMessages.js
// Import the functions you need from the SDKs you need
import { initializeApp } from "https://www.gstatic.com/firebasejs/11.6.1/firebase-app.js";
import { getAnalytics } from "https://www.gstatic.com/firebasejs/11.6.1/firebase-analytics.js";
import { getMessaging,getToken, onMessage } from "https://www.gstatic.com/firebasejs/11.6.1/firebase-messaging.js";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_AUTH_DOMAIN",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_STORAGE_BUCKET",
messagingSenderId: "YOUR_SENDER_ID",
appId: "YOUR_APP_ID"
};
const vapidKey = 'YOUR_VAPID_KEY`;
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);
//Initialize Firebase Cloud Messaging and get a reference to the service
const messaging = getMessaging(app);//firebase.messaging();
function getFCMToken()
{
// Add the public key generated from the console here.
getToken(messaging, {vapidKey: vapidKey}).then((currentToken) => {
console.log('getToken called');
if (currentToken) {
// Send the token to your server and update the UI if necessary
// ...
console.log("currentToken is " + currentToken);
fcmToken = currentToken;
} else {
// Show permission request UI
console.log('No registration token available. Request permission to generate one.');
// ...
}
}).catch((err) => {
console.log('An error occurred while retrieving token. ', err);
// ...
});
console.log('calling onMessage');
}
function requestPermission() {
console.log('Requesting permission...');
if ('Notification' in window) {
Notification.requestPermission().then(permission => {
console.log('permiss', permission);
if (permission === 'granted') {
console.log('Notification permission granted.');
} else if (permission === 'denied') {
console.warn('Notification permission denied.');
} else {
console.log('Notification permission dismissed.');
}
});
} else {
console.error('Notifications are not supported in this browser.');
}
}
//requestPermission();
function showNotification(notiTitle, notiBody) {
const notification = new Notification(notiTitle, {
body:notiBody
})
notification.onclick =(event) =>{alert("Notification clicked");};
}
if (Notification.permission === "granted") { //granted, denied, default
getFCMToken();
showNotification("New Desktop notification","Frontend stuff");
} else if (Notification.permission !== "denied") {
Notification.requestPermission().then(permission=>{
if (permission === "granted") {
getFCMToken();
showNotification("New Desktop notification","Frontend stuff");
}
})
}
onMessage(messaging, (payload) => {
console.log("Message received. ", JSON.stringify(payload));
// ...
//showNotification("Message received. ",JSON.stringify(payload));
});
HTML to receive FCM
Back to Codes
fcmRecepientFrontend.php
<!DOCTYPE html>
<html lang="en">
<head>
<title>Firebase Cloud Messaging Text Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<!-- Material I cons from Google Fonts. -->
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<script>
var fcmToken;
</script>
<script type="module" src="js/register2FCMAndReceiveMessages.js"></script>
</head>
<body>
<div class="container">
<h1>Firebase Cloud Messaging Text Example</h1>
<p>This is some text.</p>
</div>
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script>
</script>
</body>
</html>
Backend script to send message to registered devices
<?php
require 'vendor/autoload.php';
use Google\Client;
function getAccessToken($serviceAccountPath) {
$client = new Client();
$client->setAuthConfig($serviceAccountPath);
$client->addScope('https://www.googleapis.com/auth/firebase.messaging');
$client->useApplicationDefaultCredentials();
$token = $client->fetchAccessTokenWithAssertion();
return $token['access_token'];
}
function sendMessage($accessToken, $projectId, $message) {
$url = 'https://fcm.googleapis.com/v1/projects/' . $projectId . '/messages:send';
$headers = [
'Authorization: Bearer ' . $accessToken,
'Content-Type: application/json',
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['message' => $message]));
$response = curl_exec($ch);
if ($response === false) {
throw new Exception('Curl error: ' . curl_error($ch));
}
curl_close($ch);
return json_decode($response, true);
}
// Path to your service account JSON key file
$serviceAccountPath = 'path/to/your/service-account-file.json';
// Your Firebase project ID
$projectId = 'your-firebase-project-id';
// Example message payload
$message = [
'token' => 'device-token',
'notification' => [
'title' => 'Hello',
'body' => 'World',
],
];
try {
$accessToken = getAccessToken($serviceAccountPath);
$response = sendMessage($accessToken, $projectId, $message);
echo 'Message sent successfully: ' . print_r($response, true);
} catch (Exception $e) {
echo 'Error: ' . $e->getMessage();
}
?>
Backend PHP script to subscribe to topic
Back to Codes
subscribe_to_topic.php
<?php
require __DIR__ . '/../vendor/autoload.php';
use Kreait\Firebase\Factory;
$jsonData = file_get_contents("php://input");
$data = json_decode($jsonData,true);
$fcmToken = $data['fcmToken'] ?? ''; // Device token from frontend
$topic = $data['topic'] ?? 'news'; // Topic name (e.g., 'news')
if (empty($fcmToken)) {
http_response_code(400);
die(json_encode(['error' => 'FCM token is required']));
}
$serviceAccountPath = 'path/to/your/service-account-file.json';
$factory = (new Factory)->withServiceAccount($serviceAccountPath);
$messaging = $factory->createMessaging();
// Subscribe device to topic
$response = $messaging->subscribeToTopic('news', [$fcmToken]);// may use unSubscribeToTopic as well.
die(json_encode($response));
?>
Frontend JS to subscribe to topic
Back to Codes
recieveFCMMessage4Topic.js
Add the function subscribe2Topic()
below and call it inside if (currentToken) {
var topic = 'news';
function subscribe2Topic()
{
fetch('subscribe_to_topic.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ fcmToken:fcmToken, topic:topic })
})
.then(res => res.json())
.then(data => console.log('Subscribed:', data))
.catch(err => console.error('Error:', err));
console.log("Subscribed to topic " + topic);
}
Alternate method using OAuthToken from server using getAccessToken($serviceAccountPath)
fetch('https://iid.googleapis.com/iid/v1/YOUR_FCM_TOKEN/rel/topics/news', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_OAUTH2_TOKEN', // From PHP script
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
Backend PHP to send push message to topic
sendMessage2Topics.php
<?php
require __DIR__ . '/../vendor/autoload.php';
use Google\Client;
function getAccessToken($serviceAccountPath) {
$client = new Client();
$client->setAuthConfig($serviceAccountPath);
$client->addScope('https://www.googleapis.com/auth/firebase.messaging');
$client->useApplicationDefaultCredentials();
$token = $client->fetchAccessTokenWithAssertion();
return $token['access_token'];
}
function sendFCMMessage($title, $body, $topic) {
$serviceAccountPath = 'path/to/your/service-account-file.json';
// Your Firebase project ID
$projectId = 'your-firebase-project-id';
$serverKey = getAccessToken($serviceAccountPath);
//$url = 'https://fcm.googleapis.com/v1/projects/YOUR_PROJECT_ID/messages:send';
$url = 'https://fcm.googleapis.com/v1/projects/' . $projectId . '/messages:send';
$message = [
'message' => [
'topic' => $topic,
'notification' => [
'title' => $title,
'body' => $body
],
'data' => [
'extraData' => 'Some extra data'
]
]
];
$headers = [
'Authorization: Bearer ' . $serverKey,
'Content-Type: application/json'
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($message));
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
// Example usage
$title = "Hello";
$body = "This is a test notification!";
$topic = "news";
$response = sendFCMMessage($title, $body, $topic);
echo $response;
?>
Send message with Kreait
<?php
require __DIR__ . '/../vendor/autoload.php';
use Kreait\Firebase\Factory;
use Kreait\Firebase\Messaging\CloudMessage;
use Kreait\Firebase\Messaging\Notification;
$serviceAccountPath = 'path/to/your/service-account-file.json';
$factory = (new Factory)->withServiceAccount($serviceAccountPath);
$messaging = $factory->createMessaging();
// Example usage
$title = "Hello";
$body = "This is a test notification!";
$topic = "news";
// Create a CloudMessage object
$message = CloudMessage::withTarget(
'topic', // Target type: 'topic', 'token', or 'condition'
$topic // Target value (e.g., topic name or device token)
)->withNotification(
Notification::create($title, $body)
)->withData([
'key' => 'value' // Optional custom data
]);
// 4. Send the message
try {
$messaging->send($message);
echo "Message sent successfully!";
} catch (\Kreait\Firebase\Exception\MessagingException $e) {
echo "Error: " . $e->getMessage();
}
?>
|
|