Created
February 18, 2025 08:25
-
-
Save seunoyeniyi/fd8aac677a5328487c7551aa8938017b to your computer and use it in GitHub Desktop.
FCM Push Notifications with API only
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const jwt = require('jsonwebtoken'); | |
const axios = require('axios'); | |
const fs = require('fs'); | |
function getFCMAccessToken() { | |
const creds = JSON.parse(process.env.SERVICE_ACCOUNT_JSON || '{}'); | |
const privateKey = creds.private_key.replace(/\\n/g, '\n'); | |
const clientEmail = creds.client_email; | |
const scopes = ['https://www.googleapis.com/auth/firebase.messaging']; | |
const url = 'https://oauth2.googleapis.com/token'; | |
const now = Math.floor(Date.now() / 1000); | |
const payload = { | |
iss: clientEmail, | |
sub: clientEmail, | |
scope: scopes.join(' '), | |
aud: url, | |
exp: now + 10, | |
iat: now, | |
}; | |
const token = jwt.sign(payload, privateKey, { algorithm: 'RS256' }); | |
return axios.post(url, { | |
assertion: token, | |
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer' | |
}).then(response => response.data.access_token) | |
.catch(error => { | |
console.error('Error fetching access token:', error.response?.data || error.message); | |
return null; | |
}); | |
} | |
async function pushFCMByToken(token, title, content, extraData = null, picture = null) { | |
const apiKey = await getFCMAccessToken(); | |
if (!apiKey) return { code: 'error', message: 'Failed to get access token', data: null }; | |
const projectId = process.env.FIREBASE_PROJECT_ID; | |
const url = `https://fcm.googleapis.com/v1/projects/${projectId}/messages:send`; | |
const message = { | |
message: { | |
token, | |
notification: { title, body: content }, | |
data: extraData, | |
} | |
}; | |
if (picture) { | |
message.message.android = { notification: { image: picture } }; | |
message.message.apns = { payload: { aps: { 'mutable-content': 1 } }, fcm_options: { image: picture } }; | |
message.message.webpush = { headers: { image: picture } }; | |
} | |
try { | |
const response = await axios.post(url, message, { | |
headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json' } | |
}); | |
return { code: 'success', message: 'Notification sent successfully.', data: response.data }; | |
} catch (error) { | |
return { code: 'error', message: error.response?.data?.message || 'Unable to deliver notification!', data: null }; | |
} | |
} | |
async function pushFCMByTopic(topic, title, content, extraData = null, picture = null) { | |
const apiKey = await getFCMAccessToken(); | |
if (!apiKey) return { code: 'error', message: 'Failed to get access token', data: null }; | |
const projectId = process.env.FIREBASE_PROJECT_ID; | |
const url = `https://fcm.googleapis.com/v1/projects/${projectId}/messages:send`; | |
const message = { | |
message: { | |
topic, | |
notification: { title, body: content }, | |
data: extraData, | |
} | |
}; | |
if (picture) { | |
message.message.android = { notification: { image: picture } }; | |
message.message.apns = { payload: { aps: { 'mutable-content': 1 } }, fcm_options: { image: picture } }; | |
message.message.webpush = { headers: { image: picture } }; | |
} | |
try { | |
const response = await axios.post(url, message, { | |
headers: { Authorization: `Bearer ${apiKey}`, 'Content-Type': 'application/json' } | |
}); | |
return { code: 'success', message: 'Notification sent successfully.', data: response.data }; | |
} catch (error) { | |
return { code: 'error', message: error.response?.data?.message || 'Unable to deliver notification!', data: null }; | |
} | |
} | |
module.exports = { getFCMAccessToken, pushFCMByToken, pushFCMByTopic }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment