Best for
- Setting up push notifications with FCM in a Flutter project.
- Handling messages in foreground, background, and terminated states.
- Managing notification permissions and FCM tokens.
evanca/flutter-ai-rules/skills/firebase-messaging/SKILL.md
Use when setting up Firebase Cloud Messaging, managing permissions and tokens, handling background/foreground notification taps, or dispatching messages server-side (HTTP v1).
Decision brief
This skill defines how to correctly use Firebase Cloud Messaging (FCM) in Flutter applications.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/evanca/flutter-ai-rules --skill "skills/firebase-messaging"Inspect the Agent Skill "firebase-messaging" from https://github.com/evanca/flutter-ai-rules/blob/713576e02b6a17de4cc5a95ad55bdcca3a0827a6/skills/firebase-messaging/SKILL.md at commit 713576e02b6a17de4cc5a95ad55bdcca3a0827a6. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
iOS: - Enable Push Notifications and Background Modes in Xcode. - Upload your APNs authentication key to Firebase before using FCM. - Do not disable method swizzling — it is required for FCM token handling. - Ensure the bundle ID for your APNs authentication key matches your app…
Setting up push notifications with FCM in a Flutter project. Handling messages in foreground, background, and terminated states. Managing notification permissions and FCM tokens. Configuring platform-specific notification display behavior.
Background handler rules: - Must be a top-level function (not anonymous, not a class method). - Annotate with @pragma('vm:entry-point') (Flutter 3.3.0+) to prevent removal during tree shaking in release mode. - Cannot update app state or execute UI-impacting logic — runs in a se…
iOS / macOS / Web / Android 13+: Must request permission before receiving FCM payloads.
Get FCM registration token (use to send messages to a specific device):
Permission review
The documentation asks the agent to create, modify, or delete local files.
Create and register a service worker file named `firebase-messaging-sw.js` in your `web/` directory:The documentation includes network, browsing, or remote request actions.
importScripts("https://www.gstatic.com/firebasejs/10.7.0/firebase-app-compat.js");The documentation includes network, browsing, or remote request actions.
importScripts("https://www.gstatic.com/firebasejs/10.7.0/firebase-messaging-compat.js");Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 95/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 620 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
This skill defines how to correctly use Firebase Cloud Messaging (FCM) in Flutter applications.
Use this skill when:
flutter pub add firebase_messaging
iOS:
Android:
onCreate() and onResume().Web:
firebase-messaging-sw.js in your web/ directory:importScripts("https://www.gstatic.com/firebasejs/10.7.0/firebase-app-compat.js");
importScripts("https://www.gstatic.com/firebasejs/10.7.0/firebase-messaging-compat.js");
firebase.initializeApp({ /* your config */ });
const messaging = firebase.messaging();
messaging.onBackgroundMessage((message) => {
console.log("onBackgroundMessage", message);
});
Foreground messages:
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('Foreground message data: ${message.data}');
if (message.notification != null) {
print('Notification: ${message.notification}');
}
});
Background messages:
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// Initialize Firebase before using other Firebase services in background
await Firebase.initializeApp();
print("Background message: ${message.messageId}");
}
void main() {
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(MyApp());
}
Background handler rules:
@pragma('vm:entry-point') (Flutter 3.3.0+) to prevent removal during tree shaking in release mode.Firebase.initializeApp() before using any other Firebase services.NotificationSettings settings = await FirebaseMessaging.instance.requestPermission(
alert: true,
badge: true,
sound: true,
announcement: false,
carPlay: false,
criticalAlert: false,
provisional: false,
);
print('Authorization status: ${settings.authorizationStatus}');
authorizationStatus returns authorized if the user has not disabled notifications in OS settings.provisional: true) to let users choose notification types after receiving their first notification.Get FCM registration token (use to send messages to a specific device):
final fcmToken = await FirebaseMessaging.instance.getToken();
Web — provide VAPID key:
final fcmToken = await FirebaseMessaging.instance.getToken(
vapidKey: "BKagOny0KF_2pCJQ3m....moL0ewzQ8rZu"
);
Listen for token refresh:
FirebaseMessaging.instance.onTokenRefresh.listen((fcmToken) {
// Send updated token to your application server
}).onError((err) {
// Handle error
});
Apple platforms — ensure APNS token is available before FCM calls:
final apnsToken = await FirebaseMessaging.instance.getAPNSToken();
if (apnsToken != null) {
// Safe to make FCM plugin API requests
}
Token Lifecycle (Auth State): Tokens should be tied to user sessions. Save the token to your database when a user signs in, and delete the token (or remove it from the user's document) when they sign out. An FCM token is device-specific, not inherently tied to user auth data — failing to clear it on sign-out means the next user on that device might receive the previous user's notifications.
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
onMessage stream and manually display a visual cue (using your own UI logic or a local notifications plugin).meta-data to your <application> block in AndroidManifest.xml:
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="high_importance_channel" />
Disable auto-init — iOS (Info.plist):
FirebaseMessagingAutoInitEnabled = NO
Disable auto-init — Android (AndroidManifest.xml):
<meta-data android:name="firebase_messaging_auto_init_enabled" android:value="false" />
<meta-data android:name="firebase_analytics_collection_enabled" android:value="false" />
Re-enable at runtime:
await FirebaseMessaging.instance.setAutoInitEnabled(true);
Important: The iOS simulator does not display images in push notifications. Test on a physical device.
Messaging.serviceExtension().populateNotificationContent() in the extension for image handling.FirebaseMessaging Swift package to your extension target.Firebase/Messaging pod to your Podfile.When a user taps a notification, the app opens (or is brought to the foreground). Handle the interaction in both cases:
App was terminated:
RemoteMessage? initialMessage =
await FirebaseMessaging.instance.getInitialMessage();
if (initialMessage != null) {
// Navigate based on message content
}
App was in background:
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
// Navigate based on message content
});
Always handle both scenarios to ensure a smooth user experience regardless of app state when the notification was received.
// Subscribe
await FirebaseMessaging.instance.subscribeToTopic("weather_alerts");
// Unsubscribe
await FirebaseMessaging.instance.unsubscribeFromTopic("weather_alerts");
Note:
subscribeToTopic()andunsubscribeFromTopic()are not supported for web clients via the Flutter plugin.
The official Firebase documentation often obscures the exact steps for sending a test push notification. To fire a push (test or real) using the Firebase Console:
+ icon to add it.To send real automated push notifications to production users, you must use a server implementation (via the FCM HTTP v1 API or the Firebase Admin SDK) rather than the console.
The legacy FCM server key endpoint was deprecated in June 2024 — HTTP v1 is the only supported option for sending pushes.
To authenticate server-to-server calls for HTTP v1, you need a Service Account:
.json file).FIREBASE_SERVICE_ACCOUNT) to your backend.To send an FCM HTTP v1 message, your backend must:
https://www.googleapis.com/auth/firebase.messaging, endpoint https://oauth2.googleapis.com/token).POST a JSON payload to https://fcm.googleapis.com/v1/projects/{project_id}/messages:send.Here is a minimal, complete working example using Node.js and the google-auth-library:
const { GoogleAuth } = require('google-auth-library');
// Read the securely-stored service account JSON from environment
const credentials = JSON.parse(process.env.FIREBASE_SERVICE_ACCOUNT);
async function getAccessToken() {
const auth = new GoogleAuth({
credentials,
scopes: ['https://www.googleapis.com/auth/firebase.messaging']
});
const client = await auth.getClient();
const token = await client.getAccessToken();
return token.token;
}
async function sendPushNotification(fcmToken, title, body) {
const accessToken = await getAccessToken();
const projectId = credentials.project_id;
const url = `https://fcm.googleapis.com/v1/projects/${projectId}/messages:send`;
const payload = {
message: {
token: fcmToken,
notification: {
title: title,
body: body,
},
// Target specific platform features (e.g., channel on Android, sound on iOS)
android: {
notification: {
channel_id: 'high_importance_channel',
}
},
apns: {
payload: {
aps: {
sound: 'default',
}
}
}
}
};
const response = await fetch(url, {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
return response.json();
}
Frequently asked questions
This skill defines how to correctly use Firebase Cloud Messaging (FCM) in Flutter applications.
The source record exposes this install command: npx skills add https://github.com/evanca/flutter-ai-rules --skill "skills/firebase-messaging". Inspect the command and pinned source before running it.
Static rules flagged write-files, network in the source; the page lists the matching lines and excerpts.
Alternatives
coreyhaines31/marketingskills
When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program
garrytan/gbrain
End-to-end discipline for turning any large data source (audio libraries, email takeouts, document corpora, chat exports, API dumps) into brain pages at scale. The lifecycle spine: SCHEMA → ACCESS → TRIAL → EVALUATE → IMPROVE → CODIFY → TEST → SKILLIFY → BULK → MONITOR. State is tracked in a durable JSON manifest (see MANIFEST-PATTERN.md) so any crash, session boundary, or subagent fan-out resumes from ground truth instead of memory.
alirezarezvani/claude-skills
App Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklist
dotnet/skills
Migrates .NET test projects from VSTest to Microsoft.Testing.Platform (MTP). Use when user asks to "migrate to MTP", "switch from VSTest", "enable Microsoft.Testing.Platform", "use MTP runner", set OutputType=Exe only for test projects in Directory.Build.props, or mentions EnableMSTestRunner, EnableNUnitRunner, or UseMicrosoftTestingPlatformRunner. USE FOR: MTP behavioral differences vs VSTest (exit code 8, zero tests discovered, --ignore-exit-code, TESTINGPLATFORM_EXITCODE_IGNORE); centralizing