Sending Firebase Cloud Messaging notifications from terminal
Problem
If you are just starting to use Firebase Cloud Messaging, you may wonder if it is possible to send notifications to different combinations of topics, e.g. with condition.
And the answer is yes:
('en' in topics) && ('blog' in topics)
Howerver, currently it is not possible to start campaign in Firebase console with such condition.
Solution
Use Firebase Admin SDK. For example, you can write a simple command line application like this:
import {program} from "commander";
import {initializeApp} from "firebase-admin/app";
import {cert} from "firebase-admin/app";
import Handlebars from "handlebars";
import {getMessaging} from "firebase-admin/messaging";
import {readFile} from "node:fs/promises";
import {createInterface} from "node:readline";
import nestedProperty from "nested-property";
import chalk from "chalk";
const rl = createInterface({
input: process.stdin,
output: process.stdout,
})
async function q(query) {
return await new Promise(resolve => {
return rl.question(query, resolve)
})
}
program
.version("0.0.1")
.description("Command line tool for sending notifications with FCM")
.command("send <template_file> <credentials_file>")
.description("Send notification")
.action(async (template_file, credentials_file) => {
// Init app
initializeApp({
credential: cert(credentials_file)
});
const template = await readFile(template_file, 'utf8')
const compiledTemplate = Handlebars.compile(template);
let context = {}
// Ask user to enter values for all variables
for (let variable of template.matchAll(/{{[{]?(.*?)[}]?}}/g)) {
variable = variable[1].trim()
nestedProperty.set(context, variable, await q(chalk.green(`Enter ${chalk.yellow(variable)}: `)))
}
const jsonValue = compiledTemplate(context);
console.log(chalk.green("Template with applied values:"))
console.log(jsonValue);
if ((await q(chalk.yellow("Send? (y/N):"))) === 'y') {
await getMessaging().send(JSON.parse(jsonValue));
console.log(chalk.green("DONE"));
process.exit(0);
} else {
console.log(chalk.red("Cancelled"));
}
})
;
program.parse(process.argv);
Then, templating can be used to achieve great flexibility:
{
"notification": {
"title": "Check out new blogpost at captaindno.xyz",
"body": "{{ body }}"
},
"webpush": {
"fcmOptions": {
"link": "{{ link }}"
}
},
"condition": "('en' in topics) && ('blog' in topics)"
}
This is just a basic example, you may and even should make a tool that will suit your needs best.
Source code is available on GitHub
Looks like (just maybe) you are enjoying my content. Check out settings to subscribe to push-notifications or allow collections of some analytical data that helps to improve this website and its content.
Go to settings