npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

fcm-v1-token

v1.0.0

Published

Get an FCM v1 OAuth access token from a Firebase service account (cached ~1h, auto-refreshed) and send push notifications. CLI + library for Firebase Cloud Messaging HTTP v1 API.

Downloads

162

Readme

🔥 fcm-v1-token

Get an FCM v1 OAuth access token from a Firebase service account — and send push notifications — in seconds.

A tiny CLI + Node.js library that turns a Firebase service account key into a short‑lived OAuth 2.0 access token for the Firebase Cloud Messaging (FCM) HTTP v1 API. The token is cached for ~1 hour and auto‑refreshed, so you can send push notifications repeatedly without ever generating it by hand.

npm version npm downloads node license

npx fcm-v1-token

Why fcm-v1-token?

The legacy FCM server key is deprecated. The modern FCM HTTP v1 API requires a short‑lived OAuth 2.0 Bearer token generated from a service account, and that token expires after 1 hour. Generating it by hand (sign a JWT, exchange it at oauth2.googleapis.com/token, remember to refresh) is fiddly.

fcm-v1-token does it for you — from the terminal or from code:

  • 🔑 Any input — a service account file path, pasted JSON, or a credentials object
  • 🧠 Remembers your service account between runs — set it once, never paste it again
  • 🖥️ Interactive CLI — run it and pick what to do (get token / send push)
  • 🔁 Caches the token ~1 hour and auto‑refreshes it before expiry
  • 📋 Copies the token to your clipboard automatically (and prints it copy‑friendly)
  • 📤 Sends push via the FCM v1 API with a one‑line helper
  • 📦 Zero config, one dependency (google-auth-library), works with npx

Table of contents


Install

Run instantly, no install:

npx fcm-v1-token

Or install globally to get the fcm-v1-token / fcm-token / fcmt commands:

npm install -g fcm-v1-token

Or add it to a project as a library:

npm install fcm-v1-token

Quick start (CLI)

Just run it. The first time, it asks for your service account (file path, pasted JSON, or auto‑detect). After that it remembers it.

Pick Get access token and you get a color‑coded token that's already on your clipboard:

Prefer scripting? Print just the token:

# Print the raw token using your saved account
fcm-token token --raw

# Capture it into a shell variable
TOKEN=$(fcm-token token --raw)

# Use it directly against the FCM v1 API
curl -X POST \
  -H "Authorization: Bearer $(fcm-token token --raw)" \
  -H "Content-Type: application/json" \
  -d '{"message":{"token":"<device-token>","notification":{"title":"Hi","body":"Hello"}}}' \
  "https://fcm.googleapis.com/v1/projects/<your-project-id>/messages:send"

CLI commands

fcm-token                     Interactive menu (remembers your last account)
fcm-token token [source]      Print an access token
fcm-token send  [source]      Send a test push (interactive prompts)
fcm-token use   <source>      Set / replace the saved service account
fcm-token whoami              Show the saved service account
fcm-token forget              Remove the saved service account
fcm-token --help              Show help

[source] is optional — if omitted, the saved account is used. It can be a file path (./service-account.json) or JSON content ('{"type":"service_account",...}').

Options for token:

| Flag | Description | | --- | --- | | --raw | Print only the token — no color, no clipboard (for scripting) | | --json | Print full info (token, projectId, expiresAt) as JSON | | --no-copy | Do not copy the token to the clipboard |

Set NO_COLOR=1 to disable colors. The short alias fcmt works everywhere, and npx fcm-v1-token runs the same tool without installing.


Use as a library

Get an access token

const { getAccessToken } = require('fcm-v1-token');

const { token, projectId, expiresAt } = await getAccessToken('./service-account.json');
// Call getAccessToken() as often as you like — while valid, the same cached
// token is returned; it auto-refreshes when it expires (~1 hour).

Send a push notification (FCM v1)

const { sendPush } = require('fcm-v1-token');

await sendPush('./service-account.json', {
  token: '<device-registration-token>',
  notification: { title: 'Hello', body: 'World' },
  data: { orderId: '123' },
});

Send to a topic:

await sendPush('./service-account.json', {
  topic: 'news',
  notification: { title: 'Breaking', body: 'Something happened' },
});

Validate only (do not deliver):

await sendPush(serviceAccount, message, { dryRun: true });

Pass content or an object instead of a file path

// From an environment variable (recommended for servers)
const sa = JSON.parse(process.env.FIREBASE_SERVICE_ACCOUNT);
await getAccessToken(sa);

// Or a pasted JSON string
await getAccessToken('{"type":"service_account", ...}');

How it works

  1. Reads your service account's client_email and private_key.
  2. Signs a JWT and exchanges it at https://oauth2.googleapis.com/token for an OAuth 2.0 access token, scoped to https://www.googleapis.com/auth/firebase.messaging.
  3. Caches the token in memory and auto‑refreshes it before the ~1‑hour expiry (powered by google-auth-library).
  4. Uses the token as a Bearer credential against https://fcm.googleapis.com/v1/projects/<project-id>/messages:send.

No secrets ever leave your machine — the token is created and used locally.


API reference

| Function | Returns | | --- | --- | | getAccessToken(source) | { token, projectId, clientEmail, expiresAt } | | sendPush(source, message, options?) | FCM v1 response object | | loadServiceAccount(source) | validated service account object | | saveLastAccount(sa, source) | persist an account for later runs → config path | | loadLastAccount() | saved config, or null | | savedSource(saved) | a usable source from a saved config | | forgetLastAccount() | remove the saved account → boolean | | clearCache() | clear the in‑memory token cache |

  • source — a file path (string), pasted JSON content (string), or a credentials object.
  • options{ projectId?, dryRun? }.

TypeScript types are bundled (src/index.d.ts).


Where is my account stored?

~/.fcm-v1-token/config.json (permissions 0600).

  • If you passed a file path, only the absolute path is stored — your key stays in the file.
  • If you pasted JSON content, that content is stored in the config file (there is no file to re‑read).

Run fcm-token forget to remove it.


🔒 Security

A service account private key grants access to your entire Firebase project. Treat it like a password:

  • Never commit it to git — add service-account*.json to .gitignore.
  • Never paste it into a chat, issue, or screenshot. If a key is ever exposed, rotate it immediately in the Google Cloud Console → Service Accounts (delete the leaked key, create a new one).
  • On servers, prefer an environment variable or a secret manager over a file on disk.

FAQ

How do I get an FCM v1 API access token? Run npx fcm-v1-token, choose your service account once, and pick Get access token — or in code, await getAccessToken('./service-account.json'). The token is a standard Google OAuth 2.0 Bearer token valid for ~1 hour.

How long does an FCM v1 access token last? About 1 hour (3600 seconds). This tool caches it and refreshes it automatically, so you never hit an expired‑token error while sending push.

How do I send an FCM v1 push notification in Node.js? Use sendPush(source, message) — see Send a push notification. It posts to messages:send with the right Authorization: Bearer header for you.

Do I still need the legacy FCM server key? No. The legacy server key is deprecated. The HTTP v1 API uses OAuth 2.0 tokens from a service account, which is exactly what this tool produces.

Where do I get the service account JSON? Firebase Console → Project settingsService accountsGenerate new private key. That downloaded JSON is your source.

Does it work without installing? Yes — npx fcm-v1-token runs it directly. Install globally only if you want the short fcmt command always available.

Which platforms are supported for clipboard copy? macOS (pbcopy), Windows (clip), and Linux (xclip). If none is available, the token is still printed — copy it manually.


License

MIT © Sujeet Kumar


Keywords: FCM v1 access token · Firebase Cloud Messaging HTTP v1 API · OAuth 2.0 bearer token · service account to access token · send FCM push notification Node.js · firebase-admin alternative · FCM token CLI