accessibility
Use when working on accessibility, a11y, WCAG, ARIA, screen readers, keyboard nav, focus order, contrast, alt text, captions,…
Use when setting up Firebase Cloud Messaging, managing permissions and tokens, handling background/foreground notification taps, or dispatching messages server-side (HTTP v1).
Claude Code
$ npx -y skills add evanca/flutter-ai-rules --skill firebase-messaging --agent claude-code
Codex
$ npx skills add evanca/flutter-ai-rules --skill firebase-messaging -a codex -y
Cursor
$ npx skills add evanca/flutter-ai-rules --skill firebase-messaging -a cursor -y
Gemini CLI
$ npx skills add evanca/flutter-ai-rules --skill firebase-messaging -a gemini-cli -y
GitHub Copilot
$ npx skills add evanca/flutter-ai-rules --skill firebase-messaging -a github-copilot -y
OpenCode
$ npx skills add evanca/flutter-ai-rules --skill firebase-messaging -a opencode -y
Windsurf
$ npx skills add evanca/flutter-ai-rules --skill firebase-messaging -a windsurf -y
name: firebase-messaging description: "Use when setting up Firebase Cloud Messaging, managing permissions and tokens, handling background/foreground notification taps, or dispatching messages server-side (HTTP v1)." license: MIT
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:**
**Web:**
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:
---
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}');---
**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,
); <meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="high_importance_channel" />---
**Disable auto-init — iOS** (`
36 Flutter and Dart skills your coding agent loads by itself, sourced only from official documentation. A skill is a folder with a SKILL.md file.
Use when working on accessibility, a11y, WCAG, ARIA, screen readers, keyboard nav, focus order, contrast, alt text, captions,…
Use when creating a feature, designing folder structure, adding repositories/services/view models, wiring dependency injection,…
Use when creating a Cubit or Bloc, modeling state with sealed classes or status enums, wiring…
Use when asked to review a PR, MR, branch, or diff, audit changed files, or check code quality.
Use when writing switch statements, refactoring if-else chains, creating data classes, choosing records vs classes, destructuring…
Use when building AI agents in Dart, implementing Genkit flows or tools, integrating LLMs into Dart or Flutter applications, or…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.