← Files FirebaseARCHIVED FILE
reference/sdk_flutter.md
3.43 KB · Sep 30, 2026 · 23:02 UTC
# Flutter SDK
Consult this file when writing Flutter application code (Dart) that interacts
with the SQL Connect backend.
### Best Practices for Agents
- **Understand Operation Storage**: SQL Connect queries and mutations are stored
on the server like Cloud Functions. **Whenever you update operations, you must
regenerate the SDK and redeploy services** that use it to avoid breaking
clients.
- **Resilient Enum Handling**: The generated SDK forces handling of unknown
values for enumerations. Client code must unwrap the `EnumValue` object into
either `Known` or `Unknown` to handle schema updates gracefully.
- **Use Ref for Subscriptions**: Call `.ref()` on operation methods to get a
`QueryRef` for advanced usage like subscriptions.
- **Builder Pattern for Optionals**: Use the builder pattern for mutations with
optional fields.
### Installation
```bash
flutter pub add firebase_data_connect
```
### Imports
```dart
import 'package:firebase_data_connect/firebase_data_connect.dart';
// Import generated connector
import 'generated/movies.dart';
```
### Initialization
```dart
// For local development with emulator
MoviesConnector.instance.dataConnect.useDataConnectEmulator('127.0.0.1', 9399);
```
### Calling Operations
#### Basic Query
```dart
final response = await MoviesConnector.instance.listMovies().execute();
print(response.data.movies);
```
#### Mutation with Optional Fields (Builder Pattern)
```dart
await MoviesConnector.instance.createMovie(
title: 'Empire Strikes Back',
releaseYear: 1980,
genre: 'Sci-Fi'
).rating(5).execute();
```
### Resilient Enum Handling
When dealing with schema enumerations, use the forced unwrapping pattern to
handle unknown values (e.g., when a new value is added to the backend but client
is old).
```dart
final result = await MoviesConnector.instance.listMovies().execute();
if (result.data != null && result.data!.isNotEmpty) {
handleEnumValue(result.data![0].aspectratio);
}
void handleEnumValue(EnumValue<AspectRatio> aspectValue) {
if (aspectValue.value != null) {
switch(aspectValue.value!) {
case AspectRatio.ACADEMY:
print("Academy aspect");
break;
case AspectRatio.WIDESCREEN:
print("Widescreen aspect");
break;
// Add other known cases...
}
} else {
print("Unknown aspect ratio detected: ${aspectValue.stringValue}");
}
}
```
### Client-Side Caching
Enable caching in `connector.yaml` to reduce requests and support offline
scenarios.
```yaml
generate:
dartSdk: # Or the appropriate block for your project
outputDir: ../dart/
package: "dataconnect_generated"
clientCache:
maxAge: 5s
storage: memory # Or persistent for native
```
Use policies in code:
```dart
// Only serve cached values
await queryRef.execute(fetchPolicy: QueryFetchPolicy.cacheOnly);
// Unconditionally fetch fresh values
await queryRef.execute(fetchPolicy: QueryFetchPolicy.serverOnly);
```
### Real-time Subscriptions
```dart
final queryRef = MoviesConnector.instance.getMovieById(id: "<MOVIE_ID>").ref();
final subscription = queryRef.subscribe().listen((result) {
final movie = result.data.movie;
if (movie != null) {
updateUi(movie.title);
}
});
```
### Data Type Mapping Reference
- GraphQL `Timestamp` -> Dart `firebase_data_connect.Timestamp`
- GraphQL `Int` -> Dart `int`
- GraphQL `Date` -> Dart `DateTime`
- GraphQL `UUID` -> Dart `string`
- GraphQL `Float` -> Dart `double`
- GraphQL `Boolean` -> Dart `bool`
SHA-256: 3640523abf56bca4546fe6073423e697db9b328e249f8cd49b8ea8db79e3d3ee