accessibility
Use when working on accessibility, a11y, WCAG, ARIA, screen readers, keyboard nav, focus order, contrast, alt text, captions,…
Use when implementing crash reporting, capturing fatal/non-fatal errors, recording isolate/async exceptions, customizing reports, or uploading obfuscated symbols.
Claude Code
$ npx -y skills add evanca/flutter-ai-rules --skill firebase-crashlytics --agent claude-code
Codex
$ npx skills add evanca/flutter-ai-rules --skill firebase-crashlytics -a codex -y
Cursor
$ npx skills add evanca/flutter-ai-rules --skill firebase-crashlytics -a cursor -y
Gemini CLI
$ npx skills add evanca/flutter-ai-rules --skill firebase-crashlytics -a gemini-cli -y
GitHub Copilot
$ npx skills add evanca/flutter-ai-rules --skill firebase-crashlytics -a github-copilot -y
OpenCode
$ npx skills add evanca/flutter-ai-rules --skill firebase-crashlytics -a opencode -y
Windsurf
$ npx skills add evanca/flutter-ai-rules --skill firebase-crashlytics -a windsurf -y
name: firebase-crashlytics description: "Use when implementing crash reporting, capturing fatal/non-fatal errors, recording isolate/async exceptions, customizing reports, or uploading obfuscated symbols." license: MIT
This skill defines how to correctly use Firebase Crashlytics in Flutter applications.
Use this skill when:
---
flutter pub add firebase_crashlytics flutter pub add firebase_analytics # enables breadcrumb logs for better crash context
Run `flutterfire configure` to update the Firebase configuration and add the required Crashlytics Gradle plugin for Android.
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
**Obfuscated code:**
firebase crashlytics:symbols:upload --app=FIREBASE_APP_ID PATH/TO/symbols
---
Configure comprehensive error capture in `main()` to catch errors from all sources:
**Fatal Flutter errors:**
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
// Pass all uncaught fatal errors from the framework to Crashlytics
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;
// Catch async errors not handled by the Flutter framework
PlatformDispatcher.instance.onError = (error, stack) {
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
return true;
};
runApp(MyApp());
}**Non-fatal Flutter errors:** use `recordFlutterError` instead of `recordFlutterFatalError`.
**Isolate errors:**
Isolate.current.addErrorListener(RawReceivePort((pair) async {
final List<dynamic> errorAndStacktrace = pair;
await FirebaseCrashlytics.instance.recordError(
errorAndStacktrace.first,
errorAndStacktrace.last,
fatal: true,
);
}).sendPort);**Caught exceptions (non-fatal):**
await FirebaseCrashlytics.instance.recordError( error, stackTrace, reason: 'a non-fatal error', information: ['further diagnostic information about the error', 'version 2.0'], );
---
**Custom keys** (max 64 key/value pairs, up to 1 kB each):
FirebaseCrashlytics.instance.setCustomKey('str_key', 'hello');
FirebaseCrashlytics.instance.setCustomKey('bool_key', true);
FirebaseCrashlytics.instance.setCustomKey('int_key', 1);**Custom log messages** (limit: 64 kB per session):
FirebaseCrashlytics.instance.log("User tapped on payment button");**User identifier:**
FirebaseCrashlytics.instance.setUserIdentifier("user-123");
// Clear by setting to blank string
FirebaseCrashlytics.instance.setUserIdentifier("");---
**Disable Crashlytics in debug builds:**
if (kReleaseMode) {
await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true);
} else {
await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(false);
}---
Force a test crash to verify the setup:
FirebaseCrashlytics.instance.crash();
**Verification workflow:** 1. Build and run the app in release mode. 2. Trigger the test crash. 3. Reopen the app so the crash report is uploaded. 4. Check the Firebase Console Crashlytics dashboard within 5 minutes. 5. Verify that custom keys, logs, and user identifiers appear on the crash report.
---
By default, Crashlytics automatically collects crash reports for all users.
To give users control over data collection:
---
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.