Install
$ agentstack add skill-evanca-flutter-ai-rules-firebase-messaging ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Firebase Cloud Messaging Skill
This skill defines how to correctly use Firebase Cloud Messaging (FCM) in Flutter applications.
When to Use
Use this skill when:
- 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.
1. Setup and Configuration
flutter pub add firebase_messaging
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's bundle ID.
Android:
- Devices must run Android 4.4+ with Google Play services installed.
- Check for Google Play services compatibility in both
onCreate()andonResume().
Web:
- Create and register a service worker file named
firebase-messaging-sw.jsin yourweb/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);
});
2. Message Handling
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 _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:
- 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 separate isolate.
- Call
Firebase.initializeApp()before using any other Firebase services.
3. Permissions
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}');
- iOS / macOS / Web / Android 13+: Must request permission before receiving FCM payloads.
- **Android
block inAndroidManifest.xml`:
```xml
```
6. Auto-Initialization Control
Disable auto-init — iOS (Info.plist):
FirebaseMessagingAutoInitEnabled = NO
Disable auto-init — Android (AndroidManifest.xml):
Re-enable at runtime:
await FirebaseMessaging.instance.setAutoInitEnabled(true);
- The auto-init setting persists across app restarts once set.
7. iOS Image Notifications
> Important: The iOS simulator does not display images in push notifications. Test on a physical device.
- Add a Notification Service Extension in Xcode.
- Use
Messaging.serviceExtension().populateNotificationContent()in the extension for image handling. - Swift: add the
FirebaseMessagingSwift package to your extension target. - Objective-C: add the
Firebase/Messagingpod to your Podfile.
8. Notification Interaction Handling
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.
9. Topic Messaging
- Subscribing to a topic allows sending messages to multiple devices that have opted in.
- Topic messages are best suited for publicly available information (e.g., weather updates), optimized for throughput rather than latency.
// Subscribe
await FirebaseMessaging.instance.subscribeToTopic("weather_alerts");
// Unsubscribe
await FirebaseMessaging.instance.unsubscribeFromTopic("weather_alerts");
> Note: subscribeToTopic() and unsubscribeFromTopic() are not supported for web clients via the Flutter plugin.
10. Sending a Test Message
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:
- Obtain your device's FCM registration token (see Section 4).
- Go to the Firebase Console and select your project.
- In the left navigation panel, find the Engage (or Run) section and click Messaging (or Cloud Messaging).
- Click New campaign and select Notifications.
- Enter a Notification title and Notification text.
- Click Send test message (often a button on the right side of the screen).
- In the dialog, enter your FCM registration token and click the
+icon to add it. - Make sure the token is checked, then click Test.
> 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.
11. Server-Side Credentials & Security
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:
- Go to Firebase Console → Project settings → Service accounts.
- Click Generate new private key (downloads a
.jsonfile). - CRITICAL: This file contains highly sensitive secrets and must never be committed to git.
- Store the file securely (e.g., in a Secret Manager) or pass its stringified contents as an environment variable (like
FIREBASE_SERVICE_ACCOUNT) to your backend.
12. Sending Messages (HTTP v1)
To send an FCM HTTP v1 message, your backend must:
- Complete an OAuth2 JWT exchange (sign with RS256, scope
https://www.googleapis.com/auth/firebase.messaging, endpointhttps://oauth2.googleapis.com/token). - Construct and
POSTa JSON payload tohttps://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();
}
References
- Firebase Cloud Messaging Flutter documentation
- Send a test message to a backgrounded app
- Receive messages in Flutter
- Topic messaging on Flutter
- Migrate from legacy FCM APIs to HTTP v1
- Server environment authorization (for OAuth2 / Service Accounts)
- FCM HTTP v1 API Reference
- Android Receive Docs (for default channel ID)
- FirebaseMessaging setForegroundNotificationPresentationOptions (API Reference)
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: evanca
- Source: evanca/flutter-ai-rules
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.