firebase-messaging
Skill0 starsChanged 5 months agoMITView on GitHub
Configures Firebase Cloud Messaging (FCM) for push notifications — APNs key setup, Android FCM v1, requesting permission, getting and storing device tokens, topic subscriptions, sending from Cloud Functions, and deep-linking from notification taps. Use whenever the user wants to send remote push notifications to a web, iOS, or Android app.
1 other project uses a version of this.
Adopted by
Most recently taken up by
- evanca/flutter-ai-rulestheir own version, first seen Aug 24, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- evanca/flutter-ai-rules★ 669same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository15 other files it gives its agents.
- firebase-ai-logicSkill
- firebase-analyticsSkill
- firebase-app-checkSkill
- firebase-architectureSkill
- firebase-authSkill
- firebase-cloud-functionsSkill
- firebase-cost-optimizationSkill
- firebase-crashlyticsSkill
- firebase-emulatorsSkill
- firebase-expoSkill
- firebase-firestoreSkill
- firebase-hostingSkill
- firebase-realtime-databaseSkill
- firebase-remote-configSkill
- firebase-storageSkill
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 1 is distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 127
Always read routing info from msg.data (custom payload), not msg.notification — the latter is the visible text and may be empty for …
- Distinctive: line 177
Always handle the response and prune dead tokens, otherwise the array grows unbounded and every send hits failed deliveries.
- Very specific: line 205
Sending to >500 tokens with
send(): Use sendEachForMulticast (up to 500 per call, chunk for more).
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Firebase Cloud Messaging (FCM)
Minimum viable example
import messaging from "@react-native-firebase/messaging";
const status = await messaging().requestPermission();
if (status === messaging.AuthorizationStatus.AUTHORIZED) {
const token = await messaging().getToken();
// store token against user.uid in Firestore, prune on send failures
}Plus an APNs key uploaded to Firebase Console for iOS. Everything else (topics, rich notifications, background handlers) builds on this.
1. Provider setup
iOS (APNs)
- In Apple Developer portal: Keys → create an APNs Authentication Key (.p8). Download once — non-recoverable.
- Firebase Console → Project Settings → Cloud Messaging → Apple app config → upload the .p8, Key ID, and Team ID.
aps-environment must match the build:
developmentfor dev builds / TestFlight internalproductionfor App Store / TestFlight external
Android
FCM works automatically when google-services.json is wired (see firebase-expo). Newer FCM uses HTTP v1; the legacy server key path is deprecated — don't use fcm.googleapis.com/fcm/send from new code.
2. Client setup (Expo / React Native)
npx expo install @react-native-firebase/messaging{
"expo": {
"plugins": ["@react-native-firebase/app", "@react-native-firebase/messaging"],
"ios": {
"infoPlist": { "UIBackgroundModes": ["remote-notification"] },
"entitlements": { "aps-environment": "production" }
}
}
}Rebuild after editing app.json:
npx expo prebuild --clean
eas build --profile development --platform ios3. Request permission and get token
import messaging from "@react-native-firebase/messaging";
import auth from "@react-native-firebase/auth";
import firestore from "@react-native-firebase/firestore";
export async function registerForPush() {
const status = await messaging().requestPermission();
const ok = status === messaging.AuthorizationStatus.AUTHORIZED
|| status === messaging.AuthorizationStatus.PROVISIONAL;
if (!ok) return;
const token = await messaging().getToken();
const uid = auth().currentUser?.uid;
if (!uid) return;
await firestore().collection("users").doc(uid).set({
fcmTokens: firestore.FieldValue.arrayUnion(token),
}, { merge: true });
messaging().onTokenRefresh(async (newToken) => {
await firestore().collection("users").doc(uid).update({
fcmTokens: firestore.FieldValue.arrayUnion(newToken),
});
});
}Store tokens as an array per user (not a single field) — users have multiple devices. Prune dead tokens on send failure (see "sending" below).
4. Receiving messages
Foreground
useEffect(() => {
return messaging().onMessage(async (msg) => {
// iOS suppresses system banners while foregrounded. Show your own in-app banner.
});
}, []);Background → app opened from notification
useEffect(() => {
// App opened from a quit state by tapping a notification
messaging().getInitialNotification().then((msg) => {
if (msg?.data?.deepLink) router.push(msg.data.deepLink as string);
});
// App brought from background to foreground by tap
return messaging().onNotificationOpenedApp((msg) => {
if (msg?.data?.deepLink) router.push(msg.data.deepLink as string);
});
}, []);Always read routing info from msg.data (custom payload), not msg.notification — the latter is the visible text and may be empty for data-only messages.
Background message handler
Register at the top of index.js (outside React):
import messaging from "@react-native-firebase/messaging";
messaging().setBackgroundMessageHandler(async (msg) => {
// Runs in a separate JS context. Cannot touch React state.
// Useful for syncing data, updating badges, etc.
});5. Sending from a Cloud Function
import { getMessaging } from "firebase-admin/messaging";
export const notifyMention = onDocumentCreated("mentions/{id}", async (event) => {
const data = event.data?.data();
const userSnap = await getFirestore().collection("users").doc(data.userId).get();
const tokens: string[] = userSnap.data()?.fcmTokens ?? [];
if (tokens.length === 0) return;
const response = await getMessaging().sendEachForMulticast({
tokens,
notification: { title: "You were mentioned", body: data.preview },
data: { deepLink: `/posts/${data.postId}` },
apns: { payload: { aps: { badge: 1, sound: "default" } } },
android: { priority: "high" },
});
// Prune invalid tokens
const stale: string[] = [];
response.responses.forEach((r, i) => {
if (!r.success && (
r.error?.code === "messaging/registration-token-not-registered" ||
r.error?.code === "messaging/invalid-registration-token"
)) stale.push(tokens[i]);
});
if (stale.length) {
await getFirestore().collection("users").doc(data.userId).update({
fcmTokens: getFirestore.FieldValue.arrayRemove(...stale),
});
}
});Always handle the response and prune dead tokens, otherwise the array grows unbounded and every send hits failed deliveries.
6. Topics
For broadcast notifications (e.g. "users who follow team X"), use topics instead of token lists:
// Client subscribes
await messaging().subscribeToTopic("team-lakers");
// Function sends
await getMessaging().send({
topic: "team-lakers",
notification: { title: "Lakers won", body: "..." },
});Topic names must match [a-zA-Z0-9-_.~%]+. Max 5 topics per device for direct subscriptions, but server-side topic management has no limit.
For Android notification channels, custom sounds, rich notifications with images, and action buttons see references/notification-channels.md.
7. Common mistakes
- Using
expo-notificationsfor remote push. It's for local notifications only. Remote FCM requires@react-native-firebase/messaging. - Not uploading the APNs key. iOS pushes silently fail; Android works fine — easy to miss in testing.
- Reading routing info from
notificationinstead ofdata. Data-only messages have nonotificationfield. - Storing one token per user. Users have phones + tablets; store an array and prune on send failures.
- Forgetting
aps-environment. App Store builds without"production"will not receive any pushes. - Sending to >500 tokens with
send(). UsesendEachForMulticast(up to 500 per call, chunk for more).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

