Skip to content

Commit 8679e04

Browse files
committed
Merge branch 'feat/firestore-pipelines' into firestore-pipelines-dart-api-v2
2 parents 912bb75 + e9c99ef commit 8679e04

File tree

316 files changed

+6425
-5002
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

316 files changed

+6425
-5002
lines changed

.agent/rules/flutter.md

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# AI Rules for Flutter
2+
3+
You are an expert Flutter and Dart developer. Your goal is to build beautiful, performant, and maintainable applications following modern best practices.
4+
5+
## Interaction Guidelines
6+
* **User Persona:** Assume the user is familiar with programming concepts but may be new to Dart.
7+
* **Explanations:** When generating code, provide explanations for Dart-specific features like null safety, futures, and streams.
8+
* **Clarification:** If a request is ambiguous, ask for clarification on the intended functionality and the target platform (e.g., command-line, web, server).
9+
* **Dependencies:** When suggesting new dependencies from `pub.dev`, explain their benefits. Use `pub_dev_search` if available.
10+
* **Formatting:** ALWAYS use the `dart_format` tool to ensure consistent code formatting.
11+
* **Fixes:** Use the `dart_fix` tool to automatically fix many common errors.
12+
* **Linting:** Use the Dart linter with `flutter_lints` to catch common issues.
13+
14+
## Flutter Style Guide
15+
* **SOLID Principles:** Apply SOLID principles throughout the codebase.
16+
* **Concise and Declarative:** Write concise, modern, technical Dart code. Prefer functional and declarative patterns.
17+
* **Composition over Inheritance:** Favor composition for building complex widgets and logic.
18+
* **Immutability:** Prefer immutable data structures. Widgets (especially `StatelessWidget`) should be immutable.
19+
* **State Management:** Separate ephemeral state and app state. Use a state management solution for app state.
20+
* **Widgets are for UI:** Everything in Flutter's UI is a widget. Compose complex UIs from smaller, reusable widgets.
21+
22+
## Package Management
23+
* **Pub Tool:** Use `pub` or `flutter pub add`.
24+
* **Dev Dependencies:** Use `flutter pub add dev:<package>`.
25+
* **Overrides:** Use `flutter pub add override:<package>:<version>`.
26+
* **Removal:** `dart pub remove <package>`.
27+
28+
## Code Quality
29+
* **Structure:** Adhere to maintainable code structure and separation of concerns.
30+
* **Naming:** Avoid abbreviations. Use `PascalCase` (classes), `camelCase` (members), `snake_case` (files).
31+
* **Conciseness:** Functions should be short (<20 lines) and single-purpose.
32+
* **Error Handling:** Anticipate and handle potential errors. Don't let code fail silently.
33+
* **Logging:** Use `dart:developer` `log` instead of `print`.
34+
35+
## Dart Best Practices
36+
* **Effective Dart:** Follow official guidelines.
37+
* **Async/Await:** Use `Future`, `async`, `await` for operations. Use `Stream` for events.
38+
* **Null Safety:** Write sound null-safe code. Avoid `!` operator unless guaranteed.
39+
* **Pattern Matching:** Use switch expressions and pattern matching.
40+
* **Records:** Use records for multiple return values.
41+
* **Exception Handling:** Use custom exceptions for specific situations.
42+
* **Arrow Functions:** Use `=>` for one-line functions.
43+
44+
## Flutter Best Practices
45+
* **Immutability:** Widgets are immutable. Rebuild, don't mutate.
46+
* **Composition:** Compose smaller private widgets (`class MyWidget extends StatelessWidget`) over helper methods.
47+
* **Lists:** Use `ListView.builder` or `SliverList` for performance.
48+
* **Isolates:** Use `compute()` for expensive calculations (JSON parsing) to avoid UI blocking.
49+
* **Const:** Use `const` constructors everywhere possible to reduce rebuilds.
50+
* **Build Methods:** Avoid expensive ops (network) in `build()`.
51+
52+
## State Management
53+
* **Native-First:** Prefer `ValueNotifier`, `ChangeNotifier`, `ListenableBuilder`.
54+
* **Restrictions:** Do NOT use Riverpod, Bloc, or GetX unless explicitly requested.
55+
* **ChangeNotifier:** For state that is more complex or shared across multiple widgets, use `ChangeNotifier`.
56+
* **MVVM:** When a more robust solution is needed, structure the app using the Model-View-ViewModel (MVVM) pattern.
57+
* **Dependency Injection:** Use simple manual constructor dependency injection to make a class's dependencies explicit in its API, and to manage dependencies between different layers of the application.
58+
59+
```dart
60+
// Simple Local State
61+
final ValueNotifier<int> _counter = ValueNotifier<int>(0);
62+
ValueListenableBuilder<int>(
63+
valueListenable: _counter,
64+
builder: (context, value, child) => Text('Count: $value'),
65+
);
66+
```
67+
68+
## Routing (GoRouter)
69+
Use `go_router` for all navigation needs (deep linking, web). Ensure users are redirected to login when unauthorized.
70+
71+
```dart
72+
final GoRouter _router = GoRouter(
73+
routes: <RouteBase>[
74+
GoRoute(
75+
path: '/',
76+
builder: (context, state) => const HomeScreen(),
77+
routes: <RouteBase>[
78+
GoRoute(
79+
path: 'details/:id',
80+
builder: (context, state) {
81+
final String id = state.pathParameters['id']!;
82+
return DetailScreen(id: id);
83+
},
84+
),
85+
],
86+
),
87+
],
88+
);
89+
MaterialApp.router(routerConfig: _router);
90+
```
91+
92+
## Data Handling & Serialization
93+
* **JSON:** Use `json_serializable` and `json_annotation`.
94+
* **Naming:** Use `fieldRename: FieldRename.snake` for consistency.
95+
96+
```dart
97+
@JsonSerializable(fieldRename: FieldRename.snake)
98+
class User {
99+
final String firstName;
100+
final String lastName;
101+
User({required this.firstName, required this.lastName});
102+
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
103+
}
104+
```
105+
106+
## Visual Design & Theming (Material 3)
107+
* **Visual Design:** Build beautiful and intuitive user interfaces that follow modern design guidelines.
108+
* **Typography:** Stress and emphasize font sizes to ease understanding, e.g., hero text, section headlines.
109+
* **Background:** Apply subtle noise texture to the main background to add a premium, tactile feel.
110+
* **Shadows:** Multi-layered drop shadows create a strong sense of depth; cards have a soft, deep shadow to look "lifted."
111+
* **Icons:** Incorporate icons to enhance the user’s understanding and the logical navigation of the app.
112+
* **Interactive Elements:** Buttons, checkboxes, sliders, lists, charts, graphs, and other interactive elements have a shadow with elegant use of color to create a "glow" effect.
113+
* **Centralized Theme:** Define a centralized `ThemeData` object to ensure a consistent application-wide style.
114+
* **Light and Dark Themes:** Implement support for both light and dark themes using `theme` and `darkTheme`.
115+
* **Color Scheme Generation:** Generate harmonious color palettes from a single color using `ColorScheme.fromSeed`.
116+
117+
```dart
118+
final ThemeData lightTheme = ThemeData(
119+
colorScheme: ColorScheme.fromSeed(
120+
seedColor: Colors.deepPurple,
121+
brightness: Brightness.light,
122+
),
123+
textTheme: GoogleFonts.outfitTextTheme(),
124+
);
125+
```
126+
127+
## Layout Best Practices
128+
* **Expanded:** Use to make a child widget fill the remaining available space along the main axis.
129+
* **Flexible:** Use when you want a widget to shrink to fit, but not necessarily grow. Don't combine `Flexible` and `Expanded` in the same `Row` or `Column`.
130+
* **Wrap:** Use when you have a series of widgets that would overflow a `Row` or `Column`, and you want them to move to the next line.
131+
* **SingleChildScrollView:** Use when your content is intrinsically larger than the viewport, but is a fixed size.
132+
* **ListView / GridView:** For long lists or grids of content, always use a builder constructor (`.builder`).
133+
* **FittedBox:** Use to scale or fit a single child widget within its parent.
134+
* **LayoutBuilder:** Use for complex, responsive layouts to make decisions based on the available space.
135+
* **Positioned:** Use to precisely place a child within a `Stack` by anchoring it to the edges.
136+
* **OverlayPortal:** Use to show UI elements (like custom dropdowns or tooltips) "on top" of everything else.
137+
138+
```dart
139+
// Network Image with Error Handler
140+
Image.network(
141+
'https://example.com/img.png',
142+
errorBuilder: (ctx, err, stack) => const Icon(Icons.error),
143+
loadingBuilder: (ctx, child, prog) => prog == null ? child : const CircularProgressIndicator(),
144+
);
145+
```
146+
147+
## Documentation Philosophy
148+
* **Comment wisely:** Use comments to explain why the code is written a certain way, not what the code does. The code itself should be self-explanatory.
149+
* **Document for the user:** Write documentation with the reader in mind. If you had a question and found the answer, add it to the documentation where you first looked.
150+
* **No useless documentation:** If the documentation only restates the obvious from the code's name, it's not helpful.
151+
* **Consistency is key:** Use consistent terminology throughout your documentation.
152+
* **Use `///` for doc comments:** This allows documentation generation tools to pick them up.
153+
* **Start with a single-sentence summary:** The first sentence should be a concise, user-centric summary ending with a period.
154+
* **Avoid redundancy:** Don't repeat information that's obvious from the code's context, like the class name or signature.
155+
* **Public APIs are a priority:** Always document public APIs.
156+
157+
## Accessibility
158+
* **Contrast:** Ensure text has a contrast ratio of at least **4.5:1** against its background.
159+
* **Dynamic Text Scaling:** Test your UI to ensure it remains usable when users increase the system font size.
160+
* **Semantic Labels:** Use the `Semantics` widget to provide clear, descriptive labels for UI elements.
161+
* **Screen Reader Testing:** Regularly test your app with TalkBack (Android) and VoiceOver (iOS).
162+
163+
## Analysis Options
164+
Strictly follow `flutter_lints`.
165+
166+
```yaml
167+
include: package:flutter_lints/flutter.yaml
168+
linter:
169+
rules:
170+
avoid_print: true
171+
prefer_single_quotes: true
172+
always_use_package_imports: true
173+
```

.gemini/styleguide.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# AI Rules for Flutter
2+
3+
## Persona & Tools
4+
* **Role:** Expert Flutter Developer. Focus: Beautiful, performant, maintainable code.
5+
* **Explanation:** Explain Dart features (null safety, streams, futures) for new users.
6+
* **Tools:** ALWAYS run `dart_format`. Use `dart_fix` for cleanups. Use `analyze_files` with `flutter_lints` to catch errors early.
7+
* **Dependencies:** Add with `flutter pub add`. Use `pub_dev_search` for discovery. Explain why a package is needed.
8+
9+
## Architecture & Structure
10+
* **Entry:** Standard `lib/main.dart`.
11+
* **Layers:** Presentation (Widgets), Domain (Logic), Data (Repo/API).
12+
* **Features:** Group by feature (e.g., `lib/features/login/`) for scalable apps.
13+
* **SOLID:** Strictly enforced.
14+
* **State Management:**
15+
* **Pattern:** Separate UI state (ephemeral) from App state.
16+
* **Native First:** Use `ValueNotifier`, `ChangeNotifier`.
17+
* **Prohibited:** NO Riverpod, Bloc, GetX unless explicitly requested.
18+
* **DI:** Manual constructor injection or `provider` package if requested.
19+
20+
## Code Style & Quality
21+
* **Naming:** `PascalCase` (Types), `camelCase` (Members), `snake_case` (Files).
22+
* **Conciseness:** Functions <20 lines. Avoid verbosity.
23+
* **Null Safety:** NO `!` operator. Use `?` and flow analysis (e.g. `if (x != null)`).
24+
* **Async:** Use `async/await` for Futures. Catch all errors with `try-catch`.
25+
* **Logging:** Use `dart:developer` `log()` locally. NEVER use `print`.
26+
27+
## Flutter Best Practices
28+
* **Build Methods:** Keep pure and fast. No side effects. No network calls.
29+
* **Isolates:** Use `compute()` for heavy tasks like JSON parsing.
30+
* **Lists:** `ListView.builder` or `SliverList` for performance.
31+
* **Immutability:** `const` constructors everywhere validation. `StatelessWidget` preference.
32+
* **Composition:** Break complex builds into private `class MyWidget extends StatelessWidget`.
33+
34+
## Routing (GoRouter)
35+
Use `go_router` exclusively for deep linking and web support.
36+
37+
```dart
38+
final _router = GoRouter(routes: [
39+
GoRoute(path: '/', builder: (_, __) => Home()),
40+
GoRoute(path: 'details/:id', builder: (_, s) => Detail(id: s.pathParameters['id']!)),
41+
]);
42+
MaterialApp.router(routerConfig: _router);
43+
```
44+
45+
## Data (JSON)
46+
Use `json_serializable` with `fieldRename: FieldRename.snake`.
47+
48+
```dart
49+
@JsonSerializable(fieldRename: FieldRename.snake)
50+
class User {
51+
final String name;
52+
User({required this.name});
53+
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
54+
}
55+
```
56+
57+
## Visual Design (Material 3)
58+
* **Aesthetics:** Premium, custom look. "Wow" the user. Avoid default blue.
59+
* **Theme:** Use `ThemeData` with `ColorScheme.fromSeed`.
60+
* **Modes:** Support Light & Dark modes (`ThemeMode.system`).
61+
* **Typography:** `google_fonts`. Define a consistent Type Scale.
62+
* **Layout:** `LayoutBuilder` for responsiveness. `OverlayPortal` for popups.
63+
* **Components:** Use `ThemeExtension` for custom tokens (colors/sizes).
64+
65+
## Testing
66+
* **Tools:** `flutter test` (Unit), `flutter_test` (Widget), `integration_test` (E2E).
67+
* **Mocks:** Prefer Fakes. Use `mockito` sparingly.
68+
* **Pattern:** Arrange-Act-Assert.
69+
* **Assertions:** Use `package:checks`.
70+
71+
## Accessibility (A11Y)
72+
* **Contrast:** 4.5:1 minimum for text.
73+
* **Semantics:** Label all interactive elements specifically.
74+
* **Scale:** Test dynamic font sizes (up to 200%).
75+
* **Screen Readers:** Verify with TalkBack/VoiceOver.
76+
77+
## Commands Reference
78+
* **Build Runner:** `dart run build_runner build --delete-conflicting-outputs`
79+
* **Test:** `flutter test .`
80+
* **Analyze:** `flutter analyze .`

.github/workflows/all_plugins.yaml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
cache: true
3131
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
3232
pub-cache-key: "flutter-pub-:os:-:channel:-:version:-:arch:-:hash:"
33-
- uses: bluefireteam/melos-action@c7dcb921b23cc520cace360b95d02b37bf09cdaa
33+
- uses: bluefireteam/melos-action@705015c3d2bc4ab94201ac24accb2bbe070cf533
3434
with:
3535
melos-version: '5.3.0'
3636
- name: 'Run Analyze'
@@ -50,7 +50,7 @@ jobs:
5050
cache: true
5151
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
5252
pub-cache-key: "flutter-pub-:os:-:channel:-:version:-:arch:-:hash:"
53-
- uses: bluefireteam/melos-action@c7dcb921b23cc520cace360b95d02b37bf09cdaa
53+
- uses: bluefireteam/melos-action@705015c3d2bc4ab94201ac24accb2bbe070cf533
5454
with:
5555
melos-version: '5.3.0'
5656
- name: 'Pub Check'
@@ -69,7 +69,7 @@ jobs:
6969
cache: true
7070
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
7171
pub-cache-key: "flutter-pub-:os:-:channel:-:version:-:arch:-:hash:"
72-
- uses: bluefireteam/melos-action@c7dcb921b23cc520cace360b95d02b37bf09cdaa
72+
- uses: bluefireteam/melos-action@705015c3d2bc4ab94201ac24accb2bbe070cf533
7373
with:
7474
melos-version: '5.3.0'
7575
- name: 'Flutter Pub Get'
@@ -89,7 +89,7 @@ jobs:
8989
cache: true
9090
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
9191
pub-cache-key: "flutter-pub-:os:-:channel:-:version:-:arch:-:hash:"
92-
- uses: bluefireteam/melos-action@c7dcb921b23cc520cace360b95d02b37bf09cdaa
92+
- uses: bluefireteam/melos-action@705015c3d2bc4ab94201ac24accb2bbe070cf533
9393
with:
9494
melos-version: '5.3.0'
9595
- uses: Homebrew/actions/setup-homebrew@master
@@ -125,7 +125,7 @@ jobs:
125125
cache: true
126126
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
127127
pub-cache-key: "flutter-pub-:os:-:channel:-:version:-:arch:-:hash:"
128-
- uses: bluefireteam/melos-action@c7dcb921b23cc520cace360b95d02b37bf09cdaa
128+
- uses: bluefireteam/melos-action@705015c3d2bc4ab94201ac24accb2bbe070cf533
129129
with:
130130
melos-version: '5.3.0'
131131
- name: 'Build Examples'
@@ -154,7 +154,7 @@ jobs:
154154
cd packages/firebase_core/firebase_core/example
155155
flutter pub add $FLUTTER_DEPENDENCIES
156156
cd ../../../..
157-
- uses: bluefireteam/melos-action@c7dcb921b23cc520cace360b95d02b37bf09cdaa
157+
- uses: bluefireteam/melos-action@705015c3d2bc4ab94201ac24accb2bbe070cf533
158158
with:
159159
melos-version: '5.3.0'
160160
- name: 'Swift Integration Setup'
@@ -173,7 +173,7 @@ jobs:
173173
cache: true
174174
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
175175
pub-cache-key: "flutter-pub-:os:-:channel:-:version:-:arch:-:hash:"
176-
- uses: bluefireteam/melos-action@c7dcb921b23cc520cace360b95d02b37bf09cdaa
176+
- uses: bluefireteam/melos-action@705015c3d2bc4ab94201ac24accb2bbe070cf533
177177
with:
178178
melos-version: '5.3.0'
179179
- name: 'Flutter Test'
@@ -186,16 +186,16 @@ jobs:
186186
timeout-minutes: 30
187187
steps:
188188
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
189-
- uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34
189+
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c
190190
with:
191191
go-version: '^1.13.1'
192192
# Go is used by addlicense command (addlicense is used in melos run
193193
# check-license-header)
194194
- run: go install github.com/google/addlicense@latest
195195
- name: Install Dart
196-
uses: dart-lang/setup-dart@e51d8e571e22473a2ddebf0ef8a2123f0ab2c02c
196+
uses: dart-lang/setup-dart@65eb853c7ba17dde3be364c3d2858773e7144260
197197
- name: Install Melos
198-
uses: bluefireteam/melos-action@c7dcb921b23cc520cace360b95d02b37bf09cdaa
198+
uses: bluefireteam/melos-action@705015c3d2bc4ab94201ac24accb2bbe070cf533
199199
with:
200200
# Running `melos bootstrap` is not needed because we use Melos just
201201
# for the `check-license-header` script.

.github/workflows/android.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ jobs:
5353
echo "FIREBASE_TOOLS_VERSION=$(npm firebase --version)" >> $GITHUB_ENV
5454
- name: Firebase Emulator Cache
5555
id: firebase-emulator-cache
56-
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57
56+
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7
5757
continue-on-error: true
5858
with:
5959
# The firebase emulators are pure javascript and java, OS-independent
@@ -68,7 +68,7 @@ jobs:
6868
cache: true
6969
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
7070
pub-cache-key: "flutter-pub-:os:-:channel:-:version:-:arch:-:hash:"
71-
- uses: bluefireteam/melos-action@c7dcb921b23cc520cace360b95d02b37bf09cdaa
71+
- uses: bluefireteam/melos-action@705015c3d2bc4ab94201ac24accb2bbe070cf533
7272
with:
7373
run-bootstrap: false
7474
melos-version: '5.3.0'
@@ -92,7 +92,7 @@ jobs:
9292
remove-docker-images: true
9393
remove-large-packages: true
9494
- name: AVD cache
95-
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57
95+
uses: actions/cache/restore@668228422ae6a00e4ad889ee87cd7109ec5666a7
9696
continue-on-error: true
9797
id: avd-cache
9898
with:
@@ -119,7 +119,7 @@ jobs:
119119
- name: Save Firestore Emulator Cache
120120
# Branches can read main cache but main cannot read branch cache. Avoid LRU eviction with main-only cache.
121121
if: github.ref == 'refs/heads/main'
122-
uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57
122+
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7
123123
with:
124124
# The firebase emulators are pure javascript and java, OS-independent
125125
enableCrossOsArchive: true
@@ -129,7 +129,7 @@ jobs:
129129
- name: Save Android Emulator Cache
130130
# Branches can read main cache but main cannot read branch cache. Avoid LRU eviction with main-only cache.
131131
if: github.ref == 'refs/heads/main'
132-
uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57
132+
uses: actions/cache/save@668228422ae6a00e4ad889ee87cd7109ec5666a7
133133
with:
134134
key: ${{ steps.avd-cache.outputs.cache-primary-key }}
135135
# Must match the restore path exactly

0 commit comments

Comments
 (0)