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
EnumValueobject into eitherKnownorUnknownto handle schema updates gracefully. - Use Ref for Subscriptions: Call
.ref()on operation methods to get aQueryReffor advanced usage like subscriptions. - Builder Pattern for Optionals: Use the builder pattern for mutations with optional fields.
Installation
flutter pub add firebase_data_connectImports
import 'package:firebase_data_connect/firebase_data_connect.dart';
// Import generated connector
import 'generated/movies.dart'; Initialization
// For local development with emulator
MoviesConnector.instance.dataConnect.useDataConnectEmulator('127.0.0.1', 9399);Calling Operations
Basic Query
final response = await MoviesConnector.instance.listMovies().execute();
print(response.data.movies);Mutation with Optional Fields (Builder Pattern)
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).
final result = await MoviesConnector.instance.listMovies().execute();
if (result.data.movies.isNotEmpty) {
handleEnumValue(result.data.movies[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.
generate:
dartSdk: # Or the appropriate block for your project
outputDir: ../dart/
package: "dataconnect_generated"
clientCache:
maxAge: 5s
storage: memory # Or persistent for nativeUse policies in code:
// Only serve cached values
await queryRef.execute(fetchPolicy: QueryFetchPolicy.cacheOnly);
// Unconditionally fetch fresh values
await queryRef.execute(fetchPolicy: QueryFetchPolicy.serverOnly);Real-time Subscriptions
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-> Dartfirebase_data_connect.Timestamp - GraphQL
Int-> Dartint - GraphQL
Date-> DartDateTime - GraphQL
UUID-> Dartstring - GraphQL
Float-> Dartdouble - GraphQL
Boolean-> Dartbool