### Initialize Firestore and Create References in Dart Source: https://context7.com/firebase/snippets-flutter/llms.txt Demonstrates how to get the Firestore instance and create references to collections and documents. Useful for setting up data access in your Flutter app. ```dart import 'package:cloud_firestore/cloud_firestore.dart'; // Get Firestore instance final db = FirebaseFirestore.instance; // Create a reference to a specific document final alovelaceDocumentRef = db.collection("users").doc("alovelace"); // Create a reference to a collection final usersCollectionRef = db.collection("users"); // Create a reference using a path string final aLovelaceDocRef = db.doc("users/alovelace"); // Create a reference to a subcollection document final messageRef = db .collection("rooms") .doc("roomA") .collection("messages") .doc("message1"); ``` -------------------------------- ### Create Cloud Storage References in Flutter Source: https://context7.com/firebase/snippets-flutter/llms.txt This snippet demonstrates how to create references to files and directories within Firebase Cloud Storage. It covers getting the default instance, creating child references, navigating through the storage hierarchy, and using non-default buckets or secondary Firebase apps. ```dart import 'package:firebase_storage/firebase_storage'; // Get default storage instance final storage = FirebaseStorage.instance; // Get storage reference final storageRef = storage.ref(); // Create child references final imagesRef = storageRef.child('images'); final spaceRef = storageRef.child("images/space.jpg"); // Navigate with references final parentRef = spaceRef.parent; // Points to 'images' final rootRef = spaceRef.root; // Points to root // Chain references final earthRef = spaceRef.parent?.child("earth.jpg"); // Use a non-default bucket final customStorage = FirebaseStorage.instanceFor(bucket: "gs://my-custom-bucket"); // Use with a secondary Firebase app final secondApp = Firebase.app('SecondaryApp'); final secondaryStorage = FirebaseStorage.instanceFor( app: secondApp, bucket: 'gs://my-custom-bucket', ); ``` -------------------------------- ### Get Documents with a Query Source: https://context7.com/firebase/snippets-flutter/llms.txt Retrieve documents from a collection that match specific filter criteria. Use the `where` clause to define query conditions. ```dart // Get documents with a query db.collection("cities").where("capital", isEqualTo: true).get().then( (querySnapshot) { for (var docSnapshot in querySnapshot.docs) { print('${docSnapshot.id} => ${docSnapshot.data()}'); } }, ); ``` -------------------------------- ### Get All Documents in a Collection Source: https://context7.com/firebase/snippets-flutter/llms.txt Retrieve all documents within a specified collection. Iterate through the results to access individual document data. ```dart // Get all documents in a collection db.collection("cities").get().then( (querySnapshot) { for (var docSnapshot in querySnapshot.docs) { print('${docSnapshot.id} => ${docSnapshot.data()}'); } }, ); ``` -------------------------------- ### Get Documents from a Subcollection Source: https://context7.com/firebase/snippets-flutter/llms.txt Retrieve documents from a subcollection of a specific document. This allows for hierarchical data organization. ```dart // Get documents from a subcollection db.collection("cities").doc("SF").collection("landmarks").get().then( (querySnapshot) { for (var docSnapshot in querySnapshot.docs) { print('${docSnapshot.id} => ${docSnapshot.data()}'); } }, ); ``` -------------------------------- ### Get a Single Document Source: https://context7.com/firebase/snippets-flutter/llms.txt Retrieve a single document from Firestore. Specify the source (cache, server, or default) for the data retrieval. ```dart // Get a single document final docRef = db.collection("cities").doc("SF"); docRef.get().then( (DocumentSnapshot doc) { final data = doc.data() as Map; print("Document data: $data"); }, onError: (e) => print("Error getting document: $e"), ); ``` ```dart // Specify source (cache, server, or default) docRef.get(const GetOptions(source: Source.cache)).then( (res) => print("Successfully completed from cache"), onError: (e) => print("Error completing: $e"), ); ``` -------------------------------- ### Call Callable Cloud Functions from Flutter Source: https://context7.com/firebase/snippets-flutter/llms.txt Invoke Cloud Functions with typed parameters and handle responses or errors. Use `FirebaseFunctions.instance` to get the functions instance. ```dart import 'package:cloud_functions/cloud_functions.dart'; final functions = FirebaseFunctions.instance; // Call a function Future addMessage(String text) { final data = { "text": text, "push": true, }; final addMessage = functions.httpsCallable("addMessage"); return addMessage(data); } // Handle responses and errors final callable = functions.httpsCallable("addMessage"); callable({"text": "message text"}).then( (result) => print(result.data['text']), onError: (e) => print("Error calling function: $e"), ); ``` -------------------------------- ### Initialize Firebase Realtime Database Source: https://context7.com/firebase/snippets-flutter/llms.txt Sets up the Realtime Database instance, including using a secondary app and enabling offline persistence. ```dart import 'package:firebase_database/firebase_database.dart'; // Get default database instance final FirebaseDatabase database = FirebaseDatabase.instance; // Use secondary Firebase app FirebaseApp secondaryApp = Firebase.app('SecondaryApp'); FirebaseDatabase secondaryDatabase = FirebaseDatabase.instanceFor(app: secondaryApp); // Get root reference final DatabaseReference ref = FirebaseDatabase.instance.ref(); // Enable offline persistence FirebaseDatabase.instance.setPersistenceEnabled(true); ``` -------------------------------- ### List and Delete Files in Cloud Storage Source: https://context7.com/firebase/snippets-flutter/llms.txt Lists files and subdirectories within a Cloud Storage reference, and demonstrates how to delete a file. Includes error handling for operations. ```dart final storageRef = FirebaseStorage.instance.ref().child("files/uid"); // List all files and prefixes final listResult = await storageRef.listAll(); for (var prefix in listResult.prefixes) { // Subdirectories - can call listAll() recursively print("Directory: ${prefix.fullPath}"); } for (var item in listResult.items) { print("File: ${item.fullPath}"); } // Paginated listing Stream listAllPaginated(Reference ref) async* { String? pageToken; do { final listResult = await ref.list(ListOptions( maxResults: 100, pageToken: pageToken, )); yield listResult; pageToken = listResult.nextPageToken; } while (pageToken != null); } // Delete a file final desertRef = storageRef.child("images/desert.jpg"); await desertRef.delete(); // Error handling try { final listResult = await storageRef.listAll(); } on FirebaseException catch (e) { print("Failed with error '${e.code}': ${e.message}"); } ``` -------------------------------- ### Read and Write Data in Realtime Database Source: https://context7.com/firebase/snippets-flutter/llms.txt Demonstrates basic CRUD operations, including writing data, updating specific fields or nested paths, and reading data with listeners or once. ```dart final DatabaseReference ref = FirebaseDatabase.instance.ref(); // Write data await ref.set({ "name": "John", "age": 18, "address": {"line1": "100 Mountain View"} }); // Update specific fields await ref.update({"age": 19}); // Update nested paths await ref.update({ "123/age": 19, "123/address/line1": "1 Mountain View", }); // Read data with listener const postId = '123'; DatabaseReference starCountRef = FirebaseDatabase.instance.ref('posts/$postId/starCount'); starCountRef.onValue.listen((DatabaseEvent event) { final data = event.snapshot.value; print("Star count: $data"); }); // Read data once const userId = '123'; final dbRef = FirebaseDatabase.instance.ref(); try { final snapshot = await dbRef.child('users/$userId').get(); if (snapshot.exists) { print("User data: ${snapshot.value}"); } } on FirebaseException catch (e) { print("Error: $e"); } // Write with completion callback FirebaseDatabase.instance .ref('users/123/email') .set('user@example.com') .then((_) { print("Data saved successfully!"); }).catchError((error) { print("Write failed: $error"); }); ``` -------------------------------- ### Manage Lists and Child Events in Realtime Database Source: https://context7.com/firebase/snippets-flutter/llms.txt Shows how to push new items to a list, listen for child added, changed, and removed events, and process all values in a list. ```dart // Push to create new list item with unique key DatabaseReference postListRef = FirebaseDatabase.instance.ref("posts"); DatabaseReference newPostRef = postListRef.push(); newPostRef.set({ "title": "New Post", "body": "Post content" }); // Listen for child events final commentsRef = FirebaseDatabase.instance.ref("post-comments/123"); commentsRef.onChildAdded.listen((event) { print("New comment added: ${event.snapshot.value}"); }); commentsRef.onChildChanged.listen((event) { print("Comment changed: ${event.snapshot.value}"); }); commentsRef.onChildRemoved.listen((event) { print("Comment removed: ${event.snapshot.key}"); }); // Listen for all values postListRef.onValue.listen((event) { for (final child in event.snapshot.children) { print("Post: ${child.value}"); } }, onError: (error) { print("Error: $error"); }); ``` -------------------------------- ### Implement Pagination with Cursors in Dart Source: https://context7.com/firebase/snippets-flutter/llms.txt Use startAt, endAt, and startAfterDocument to implement cursor-based pagination. This allows you to fetch data in manageable chunks, improving performance. ```dart // Pagination with cursors db.collection("cities").orderBy("population").startAt([1000000]); db.collection("cities").orderBy("population").endAt([1000000]); // Paginate using document snapshots final first = db.collection("cities").orderBy("population").limit(25); first.get().then((documentSnapshots) { // Get the last visible document final lastVisible = documentSnapshots.docs[documentSnapshots.size - 1]; // Construct next query starting after this document final next = db .collection("cities") .orderBy("population") .startAfterDocument(lastVisible) .limit(25); }); ``` -------------------------------- ### Apple Sign-In for Web in Flutter Source: https://context7.com/firebase/snippets-flutter/llms.txt A simplified approach for Apple Sign-In on web platforms using `signInWithPopup` with specified scopes. ```dart Future signInWithAppleWeb() async { final provider = OAuthProvider("apple.com") ..addScope('email') ..addScope('name'); return await FirebaseAuth.instance.signInWithPopup(provider); } ``` -------------------------------- ### Google Sign-In for Web in Flutter Source: https://context7.com/firebase/snippets-flutter/llms.txt Handles Google Sign-In on web platforms using `signInWithPopup` or `signInWithRedirect`. Allows adding scopes and custom parameters like `login_hint`. ```dart Future signInWithGoogleWeb() async { GoogleAuthProvider googleProvider = GoogleAuthProvider(); googleProvider.addScope('https://www.googleapis.com/auth/contacts.readonly'); googleProvider.setCustomParameters({'login_hint': 'user@example.com'}); return await FirebaseAuth.instance.signInWithPopup(googleProvider); // Or use: FirebaseAuth.instance.signInWithRedirect(googleProvider); } ``` -------------------------------- ### Listen to Query Results in Real-time Source: https://context7.com/firebase/snippets-flutter/llms.txt Listen for real-time updates to documents that match a specific query. Changes to documents satisfying the query are streamed. ```dart // Listen to query results db.collection("cities") .where("state", isEqualTo: "CA") .snapshots() .listen((event) { final cities = []; for (var doc in event.docs) { cities.add(doc.data()["name"]); } print("cities in CA: ${cities.join(", ")}"); }); ``` -------------------------------- ### Listen to a Single Document in Real-time Source: https://context7.com/firebase/snippets-flutter/llms.txt Listen for real-time updates to a single document. Changes are streamed automatically as they occur. Handles errors during the listen process. ```dart // Listen to a single document final docRef = db.collection("cities").doc("SF"); docRef.snapshots().listen( (event) => print("current data: ${event.data()}"), onError: (error) => print("Listen failed: $error"), ); ``` -------------------------------- ### Listen to Document Changes (Added, Modified, Removed) Source: https://context7.com/firebase/snippets-flutter/llms.txt Listen for real-time updates on documents matching a query and process individual document changes (added, modified, or removed). ```dart // Listen to document changes (added, modified, removed) db.collection("cities") .where("state", isEqualTo: "CA") .snapshots() .listen((event) { for (var change in event.docChanges) { switch (change.type) { case DocumentChangeType.added: print("New City: ${change.doc.data()}"); break; case DocumentChangeType.modified: print("Modified City: ${change.doc.data()}"); break; case DocumentChangeType.removed: print("Removed City: ${change.doc.data()}"); break; } } }); ``` -------------------------------- ### Upload Files to Cloud Storage Source: https://context7.com/firebase/snippets-flutter/llms.txt Upload files from various sources like file paths, raw data, or strings. Monitor upload progress and manage the upload task. Requires `dart:io` and `path_provider` imports. ```dart import 'dart:io'; import 'package:path_provider/path_provider.dart'; final appDocDir = await getApplicationDocumentsDirectory(); final filePath = "${appDocDir.path}/mountains.jpg"; final file = File(filePath); final storageRef = FirebaseStorage.instance.ref(); final mountainsRef = storageRef.child("mountains.jpg"); // Upload with metadata final metadata = SettableMetadata(contentType: "image/jpeg"); final uploadTask = storageRef .child("images/mountains.jpg") .putFile(file, metadata); // Monitor upload progress uploadTask.snapshotEvents.listen((TaskSnapshot taskSnapshot) { switch (taskSnapshot.state) { case TaskState.running: final progress = 100.0 * (taskSnapshot.bytesTransferred / taskSnapshot.totalBytes); print("Upload is $progress% complete."); break; case TaskState.paused: print("Upload is paused."); break; case TaskState.canceled: print("Upload was canceled"); break; case TaskState.error: // Handle error break; case TaskState.success: // Handle success break; } }); // Upload from string (base64, data URL, etc.) String dataUrl = 'data:text/plain;base64,SGVsbG8sIFdvcmxkIQ=='; await mountainsRef.putString(dataUrl, format: PutStringFormat.dataUrl); // Manage upload task final task = mountainsRef.putFile(file); bool paused = await task.pause(); bool resumed = await task.resume(); bool canceled = await task.cancel(); // Get download URL after upload final downloadUrl = await mountainsRef.getDownloadURL(); ``` -------------------------------- ### Apple Sign-In with Nonce Generation in Flutter Source: https://context7.com/firebase/snippets-flutter/llms.txt Authenticate users with Apple ID, including secure nonce generation and SHA256 hashing for replay attack prevention. Requires `sign_in_with_apple` and `crypto` packages. ```dart import 'dart:convert'; import 'dart:math'; import 'package:crypto/crypto.dart'; import 'package:sign_in_with_apple/sign_in_with_apple.dart'; String generateNonce([int length = 32]) { const charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._'; final random = Random.secure(); return List.generate(length, (_) => charset[random.nextInt(charset.length)]).join(); } String sha256ofString(String input) { final bytes = utf8.encode(input); final digest = sha256.convert(bytes); return digest.toString(); } Future signInWithApple() async { final rawNonce = generateNonce(); final nonce = sha256ofString(rawNonce); final appleCredential = await SignInWithApple.getAppleIDCredential( scopes: [ AppleIDAuthorizationScopes.email, AppleIDAuthorizationScopes.fullName, ], nonce: nonce, ); final oauthCredential = OAuthProvider("apple.com").credential( idToken: appleCredential.identityToken, rawNonce: rawNonce, ); return await FirebaseAuth.instance.signInWithCredential(oauthCredential); } ``` -------------------------------- ### Download Files from Cloud Storage Source: https://context7.com/firebase/snippets-flutter/llms.txt Download files to memory or local files, or retrieve their download URLs. Handles different reference types (path, gs, https). Requires `dart:io` and `path_provider` imports. ```dart final storageRef = FirebaseStorage.instance.ref(); // Create references from various sources final pathReference = storageRef.child("images/stars.jpg"); final gsReference = FirebaseStorage.instance .refFromURL("gs://YOUR_BUCKET/images/stars.jpg"); final httpsReference = FirebaseStorage.instance .refFromURL("https://firebasestorage.googleapis.com/b/YOUR_BUCKET/o/images%20stars.jpg"); // Download to memory (max 1MB in this example) final islandRef = storageRef.child("images/island.jpg"); try { const oneMegabyte = 1024 * 1024; final Uint8List? data = await islandRef.getData(oneMegabyte); // Use data... } on FirebaseException catch (e) { print("Error: ${e.message}"); } // Download to local file final appDocDir = await getApplicationDocumentsDirectory(); final filePath = "${appDocDir.path}/images/island.jpg"; final file = File(filePath); final downloadTask = islandRef.writeToFile(file); downloadTask.snapshotEvents.listen((taskSnapshot) { switch (taskSnapshot.state) { case TaskState.running: break; case TaskState.success: print("Download complete!"); break; case TaskState.error: print("Download failed"); break; default: break; } }); // Get download URL (for use with image loading, etc.) final imageUrl = await storageRef.child("users/me/profile.png").getDownloadURL(); ``` -------------------------------- ### Google Sign-In for Mobile in Flutter Source: https://context7.com/firebase/snippets-flutter/llms.txt Authenticate users with their Google accounts on mobile platforms. Requires the `google_sign_in` package. ```dart import 'package:google_sign_in/google_sign_in.dart'; Future signInWithGoogle() async { // Trigger the authentication flow final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn(); // Obtain the auth details from the request final GoogleSignInAuthentication? googleAuth = await googleUser?.authentication; // Create a new credential final credential = GoogleAuthProvider.credential( accessToken: googleAuth?.accessToken, idToken: googleAuth?.idToken, ); // Sign in with Firebase return await FirebaseAuth.instance.signInWithCredential(credential); } ``` -------------------------------- ### Firebase Email/Password Authentication Source: https://context7.com/firebase/snippets-flutter/llms.txt Create accounts and sign in users with email and password credentials. Handles common FirebaseAuthException errors for weak passwords or existing accounts. ```dart const emailAddress = 'user@example.com'; const password = 'securePassword123!'; // Create a new account try { final credential = await FirebaseAuth.instance.createUserWithEmailAndPassword( email: emailAddress, password: password, ); print("Account created: ${credential.user?.uid}"); } on FirebaseAuthException catch (e) { if (e.code == 'weak-password') { print('The password provided is too weak.'); } else if (e.code == 'email-already-in-use') { print('The account already exists for that email.'); } } ``` ```dart // Sign in with email and password try { final credential = await FirebaseAuth.instance.signInWithEmailAndPassword( email: emailAddress, password: password, ); } on FirebaseAuthException catch (e) { if (e.code == 'user-not-found') { print('No user found for that email.'); } else if (e.code == 'wrong-password') { print('Wrong password provided for that user.'); } } ``` ```dart // Sign out await FirebaseAuth.instance.signOut(); ``` -------------------------------- ### Fetch Remote Config Values in Flutter Source: https://context7.com/firebase/snippets-flutter/llms.txt Configure and fetch remote configuration values. Set a minimum fetch interval and default values before fetching. The `fetchAndActivate` method retrieves and applies new values. ```dart import 'package:firebase_remote_config/firebase_remote_config.dart'; final remoteConfig = FirebaseRemoteConfig.instance; // Set minimum fetch interval remoteConfig.settings.minimumFetchInterval = const Duration(hours: 1); // Set default values remoteConfig.setDefaults({ 'welcome_message': 'Welcome to the app!', 'feature_enabled': false, }); // Get values (uses cached or default values) final welcomeMessage = remoteConfig.getValue("welcome_message"); final featureEnabled = remoteConfig.getBool("feature_enabled"); // Fetch and activate new values remoteConfig.fetchAndActivate().then((bool updated) { if (updated) { final allConfig = remoteConfig.getAll(); print("Config updated: $allConfig"); } }); ``` -------------------------------- ### Query and Sort Data in Flutter Realtime Database Source: https://context7.com/firebase/snippets-flutter/llms.txt Learn how to query and sort data from Firebase Realtime Database using various methods like orderByChild, orderByValue, and limitToLast. This is useful for retrieving specific subsets of data. ```dart // Order by child value final myUserId = FirebaseAuth.instance.currentUser?.uid; final topUserPostsRef = FirebaseDatabase.instance .ref("user-posts/$myUserId") .orderByChild("starCount"); // Order by nested child final mostViewedPosts = FirebaseDatabase.instance .ref('posts') .orderByChild('metrics/views'); // Limit results final recentPostsRef = FirebaseDatabase.instance .ref('posts') .limitToLast(100); // Query offline data final scoresRef = FirebaseDatabase.instance.ref("scores"); scoresRef.orderByValue().limitToLast(4).onChildAdded.listen((event) { print("${event.snapshot.key}: ${event.snapshot.value}"); }); ``` -------------------------------- ### Add Data to Firestore Source: https://github.com/firebase/snippets-flutter/blob/main/README.md Demonstrates how to add a new document with a generated ID to a Firestore collection. Ensure you have initialized Firestore. ```dart void getStarted_addData() async { // [START get_started_add_data_1] // Create a new user with a first and last name final user = { "first": "Ada", "last": "Lovelace", "born": 1815 }; // Add a new document with a generated ID db.collection("users").add(user).then((DocumentReference doc) => print('DocumentSnapshot added with ID: ${doc.id}')); // [END get_started_add_data_1] } ``` -------------------------------- ### Manage File Metadata in Cloud Storage Source: https://context7.com/firebase/snippets-flutter/llms.txt Read, update, and set metadata for files in Cloud Storage. This includes content type, cache control, and custom metadata. Requires `FirebaseStorage.instance.ref()`. ```dart final storageRef = FirebaseStorage.instance.ref(); final forestRef = storageRef.child("images/forest.jpg"); // Get metadata final metadata = await forestRef.getMetadata(); print("Content type: ${metadata.contentType}"); // Update metadata final newMetadata = SettableMetadata( cacheControl: "public,max-age=300", contentType: "image/jpeg", ); final updatedMetadata = await forestRef.updateMetadata(newMetadata); // Set custom metadata final customMetadata = SettableMetadata( customMetadata: { "location": "Yosemite, CA, USA", "activity": "Hiking", }, ); await forestRef.updateMetadata(customMetadata); // Delete metadata (set to null) final deleteMetadata = SettableMetadata(cacheControl: null); await forestRef.updateMetadata(deleteMetadata); ``` -------------------------------- ### Build Queries with Comparison Operators in Dart Source: https://context7.com/firebase/snippets-flutter/llms.txt Use comparison operators like isLessThan, isGreaterThanOrEqualTo, and isLessThanOrEqualTo to filter query results. Ensure the field type is consistent for reliable comparisons. ```dart final citiesRef = db.collection("cities"); // Simple equality query final query = citiesRef.where("state", isEqualTo: "CA"); final capitalCities = citiesRef.where("capital", isEqualTo: true); // Comparison operators final populationQuery = citiesRef.where("population", isLessThan: 100000); final stateQuery = citiesRef .where("state", isGreaterThanOrEqualTo: "CA") .where("state", isLessThanOrEqualTo: "IN"); // Not equal final notCapitals = citiesRef.where("capital", isNotEqualTo: true); // Array membership final westCoastCities = citiesRef.where("regions", arrayContains: "west_coast"); final coastalCities = citiesRef.where("regions", arrayContainsAny: ["west_coast", "east_coast"]); // In queries final cities = citiesRef.where("country", whereIn: ["USA", "Japan"]); final otherCities = citiesRef.where("country", whereNotIn: ["USA", "Japan"]); // Compound queries citiesRef .where("state", isEqualTo: "CO") .where("name", isEqualTo: "Denver"); ``` -------------------------------- ### Detect Local vs Server Changes Source: https://context7.com/firebase/snippets-flutter/llms.txt Differentiate between local changes (pending writes) and server-committed changes when listening to document snapshots. Access metadata to determine the source. ```dart // Detect local vs server changes docRef.snapshots().listen((event) { final source = (event.metadata.hasPendingWrites) ? "Local" : "Server"; print("$source data: ${event.data()}"); }); ``` -------------------------------- ### Anonymous and Custom Token Sign-in in Flutter Source: https://context7.com/firebase/snippets-flutter/llms.txt Implement anonymous sign-in for temporary accounts or use custom tokens for server-backed authentication. This snippet also shows how to link anonymous accounts to permanent credentials and unlink providers. ```dart // Anonymous sign-in try { final userCredential = await FirebaseAuth.instance.signInAnonymously(); print("Signed in with temporary account."); } on FirebaseAuthException catch (e) { if (e.code == "operation-not-allowed") { print("Anonymous auth hasn't been enabled for this project."); } } ``` ```dart // Custom token sign-in (token from your server) const token = 'your-custom-token'; try { final userCredential = await FirebaseAuth.instance.signInWithCustomToken(token); print("Sign-in successful."); } on FirebaseAuthException catch (e) { switch (e.code) { case "invalid-custom-token": print("The supplied token is not a Firebase custom auth token."); break; case "custom-token-mismatch": print("The supplied token is for a different Firebase project."); break; } } ``` ```dart // Link anonymous account to permanent credentials final credential = GoogleAuthProvider.credential(idToken: 'idToken'); try { final userCredential = await FirebaseAuth.instance.currentUser ?.linkWithCredential(credential); } on FirebaseAuthException catch (e) { switch (e.code) { case "provider-already-linked": print("The provider has already been linked to the user."); break; case "credential-already-in-use": print("The account already exists."); break; } } ``` ```dart // Unlink a provider await FirebaseAuth.instance.currentUser?.unlink('google.com'); ``` -------------------------------- ### Custom Objects with Type Converters in Dart Source: https://context7.com/firebase/snippets-flutter/llms.txt Demonstrates how to use `withConverter()` to automatically serialize and deserialize custom Dart objects to and from Firestore documents. This simplifies data handling for complex types. ```dart class City { final String? name; final String? state; final String? country; final bool? capital; final int? population; final List? regions; City({ this.name, this.state, this.country, this.capital, this.population, this.regions, }); factory City.fromFirestore( DocumentSnapshot> snapshot, SnapshotOptions? options, ) { final data = snapshot.data(); return City( name: data?['name'], state: data?['state'], country: data?['country'], capital: data?['capital'], population: data?['population'], regions: data?['regions'] is Iterable ? List.from(data?['regions']) : null, ); } Map toFirestore() { return { if (name != null) "name": name, if (state != null) "state": state, if (country != null) "country": country, if (capital != null) "capital": capital, if (population != null) "population": population, if (regions != null) "regions": regions, }; } } // Using custom objects with Firestore final city = City( name: "Los Angeles", state: "CA", country: "USA", capital: false, population: 5000000, regions: ["west_coast", "socal"], ); final docRef = db .collection("cities") .withConverter( fromFirestore: City.fromFirestore, toFirestore: (City city, options) => city.toFirestore(), ) .doc("LA"); await docRef.set(city); // Reading with custom objects final ref = db.collection("cities").doc("LA").withConverter( fromFirestore: City.fromFirestore, toFirestore: (City city, _) => city.toFirestore(), ); final docSnap = await ref.get(); final cityObj = docSnap.data(); // Returns City object ``` -------------------------------- ### Combine AND/OR Queries in Dart Source: https://context7.com/firebase/snippets-flutter/llms.txt Construct complex queries by nesting Filter.and and Filter.or conditions. This allows for sophisticated data retrieval based on multiple criteria. ```dart var query3 = db.collection("cities").where( Filter.and( Filter("state", isEqualTo: "CA"), Filter.or( Filter("capital", isEqualTo: true), Filter("population", isGreaterThan: 1000000), ), ), ); ``` -------------------------------- ### Implement OR Queries with Filter in Dart Source: https://context7.com/firebase/snippets-flutter/llms.txt Combine multiple conditions using Filter.or for flexible querying. This is useful when a document can satisfy any of the specified conditions. ```dart var query2 = db.collection("cities").where( Filter.or( Filter("capital", isEqualTo: true), Filter("population", isGreaterThan: 1000000), ), ); ``` -------------------------------- ### Order and Limit Query Results in Dart Source: https://context7.com/firebase/snippets-flutter/llms.txt Sort query results by one or more fields in ascending or descending order and limit the number of documents returned. This is fundamental for displaying data sets. ```dart final citiesRef = db.collection("cities"); // Order by field citiesRef.orderBy("name").limit(3); // Descending order citiesRef.orderBy("name", descending: true).limit(3); // Multiple order fields citiesRef.orderBy("state").orderBy("population", descending: true); // Combine with filters citiesRef .where("population", isGreaterThan: 100000) .orderBy("population") .limit(2); ``` -------------------------------- ### Listen to Firebase Auth State Changes Source: https://context7.com/firebase/snippets-flutter/llms.txt Monitor authentication state changes to react when users sign in or out. This listener provides real-time updates on the user's authentication status. ```dart import 'package:firebase_auth/firebase_auth.dart'; // Listen to auth state changes FirebaseAuth.instance.authStateChanges().listen((User? user) { if (user != null) { final uid = user.uid; print("User signed in: $uid"); } else { print("User signed out"); } }); ``` ```dart // Listen to ID token changes FirebaseAuth.instance.idTokenChanges().listen((User? user) { if (user != null) { // User signed in or token refreshed } }); ``` ```dart // Listen to user changes (profile updates, etc.) FirebaseAuth.instance.userChanges().listen((User? user) { if (user == null) { print('User is currently signed out!'); } else { print('User is signed in!'); } }); ``` ```dart // Get current user synchronously final user = FirebaseAuth.instance.currentUser; if (user != null) { final uid = user.uid; } ``` -------------------------------- ### Track E-commerce Events in Firebase Analytics Source: https://context7.com/firebase/snippets-flutter/llms.txt Track e-commerce actions such as viewing items, adding to cart, initiating checkout, and purchases. Ensure `AnalyticsEventItem` is properly defined for each product. ```dart // Define product items final jeggings = AnalyticsEventItem( itemId: "SKU_123", itemName: "jeggings", itemCategory: "pants", itemVariant: "black", itemBrand: "Google", price: 9.99, ); // Log view item list await FirebaseAnalytics.instance.logViewItemList( itemListId: "L001", itemListName: "Related products", items: [jeggings], ); // Log add to cart await FirebaseAnalytics.instance.logAddToCart( currency: 'USD', value: 19.98, items: [AnalyticsEventItem( itemId: jeggings.itemId, itemName: jeggings.itemName, price: jeggings.price, quantity: 2, )], ); // Log begin checkout await FirebaseAnalytics.instance.logBeginCheckout( currency: 'USD', value: 15.98, coupon: "SUMMER_FUN", items: [jeggings], ); // Log purchase await FirebaseAnalytics.instance.logPurchase( transactionId: "12345", affiliation: "Google Store", currency: 'USD', value: 15.98, shipping: 2.00, tax: 1.66, coupon: "SUMMER_FUN", items: [jeggings], ); // Log refund await FirebaseAnalytics.instance.logRefund( transactionId: "12345", currency: 'USD', value: 15.98, ); ``` -------------------------------- ### Set User Properties and Track Screens in Firebase Analytics Source: https://context7.com/firebase/snippets-flutter/llms.txt Set user identifiers and custom properties for segmentation, and track screen views to monitor user navigation within the app. ```dart // Set user ID FirebaseAnalytics.instance.setUserId(id: "123456"); // Set user property await FirebaseAnalytics.instance.setUserProperty( name: 'favorite_food', value: 'banana', ); // Track screen views await FirebaseAnalytics.instance.setCurrentScreen( screenName: 'Products', ); ``` -------------------------------- ### Add Data to Firestore in Dart Source: https://context7.com/firebase/snippets-flutter/llms.txt Shows how to add documents to Firestore collections using `add()` for auto-generated IDs or `set()` for specific IDs. Supports various data types. Use `set()` with `SetOptions(merge: true)` to update existing fields. ```dart // Create a new user with a first and last name final user = { "first": "Ada", "last": "Lovelace", "born": 1815 }; // Add a new document with a generated ID db.collection("users").add(user).then((DocumentReference doc) => print('DocumentSnapshot added with ID: ${doc.id}')); // Set a document with a specific ID final city = { "name": "Los Angeles", "state": "CA", "country": "USA" }; db .collection("cities") .doc("LA") .set(city) .onError((e, _) => print("Error writing document: $e")); // Set with merge option (updates existing fields, creates if doesn't exist) final data = {"capital": true}; db.collection("cities").doc("BJ").set(data, SetOptions(merge: true)); // Add various data types final docData = { "stringExample": "Hello world!", "booleanExample": true, "numberExample": 3.14159265, "dateExample": Timestamp.now(), "listExample": [1, 2, 3], "nullExample": null, "objectExample": { "a": 5, "b": true, } }; db.collection("data").doc("one").set(docData); ``` -------------------------------- ### Manage User Profile in Flutter Source: https://context7.com/firebase/snippets-flutter/llms.txt Access and update user profile details like display name, email, and photo URL. Handles potential FirebaseAuthExceptions during updates. ```dart final user = FirebaseAuth.instance.currentUser; if (user != null) { // Get user profile final name = user.displayName; final email = user.email; final photoUrl = user.photoURL; final emailVerified = user.emailVerified; final uid = user.uid; // Get provider-specific profile data for (final providerProfile in user.providerData) { final provider = providerProfile.providerId; final providerUid = providerProfile.uid; final providerName = providerProfile.displayName; final providerEmail = providerProfile.email; final providerPhotoUrl = providerProfile.photoURL; } } // Update profile try { await user?.updateDisplayName("Jane Q. User"); await user?.updatePhotoURL("https://example.com/profile.jpg"); } on FirebaseAuthException catch (e) { print("Error updating profile: $e"); } // Update email await user?.updateEmail('newemail@example.com'); // Update password await user?.updatePassword('newSecurePassword'); // Send email verification await user?.sendEmailVerification(); // Send password reset email await FirebaseAuth.instance.sendPasswordResetEmail(email: 'user@example.com'); // Set language for emails await FirebaseAuth.instance.setLanguageCode("fr"); // Delete user account await user?.delete(); ``` -------------------------------- ### Log Firebase Analytics Events Source: https://context7.com/firebase/snippets-flutter/llms.txt Log predefined and custom analytics events to track user actions. Use `setDefaultEventParameters` to set global parameters for all subsequent events. ```dart import 'package:firebase_analytics/firebase_analytics.dart'; // Log predefined event await FirebaseAnalytics.instance.logSelectContent( contentType: "image", itemId: '1234', ); // Log event with parameters await FirebaseAnalytics.instance.logEvent( name: "select_content", parameters: { "content_type": "image", "item_id": '1234', }, ); // Log custom event await FirebaseAnalytics.instance.logEvent( name: "share_image", parameters: { "image_name": 'rivers.jpg', "full_text": 'This is the full text.', }, ); // Set default event parameters await FirebaseAnalytics.instance.setDefaultEventParameters({ 'version': '1.2.3' }); ``` -------------------------------- ### Count Documents in a Collection with Dart Source: https://context7.com/firebase/snippets-flutter/llms.txt Efficiently count the number of documents in a collection or a filtered subset using the count() aggregation. This avoids downloading all documents. ```dart // Count documents in a collection db.collection("cities").count().get().then( (res) => print(res.count), ); // Count with query filter db.collection("cities") .where("capital", isEqualTo: true) .count() .get() .then((res) => print(res.count)); ``` -------------------------------- ### Configure Firestore Offline Persistence Source: https://context7.com/firebase/snippets-flutter/llms.txt Configure offline persistence and cache settings for Firestore. This allows your app to read and write data even when offline, synchronizing when connectivity is restored. Persistence is enabled by default on mobile platforms. ```dart // Enable persistence (Apple and Android) db.settings = const Settings(persistenceEnabled: true); ``` ```dart // Enable persistence on web await db.enablePersistence(const PersistenceSettings(synchronizeTabs: true)); ``` ```dart // Configure cache size db.settings = const Settings( persistenceEnabled: true, cacheSizeBytes: Settings.CACHE_SIZE_UNLIMITED, ); ``` ```dart // Listen to offline data db.collection("cities") .where("state", isEqualTo: "CA") .snapshots(includeMetadataChanges: true) .listen((querySnapshot) { for (var change in querySnapshot.docChanges) { if (change.type == DocumentChangeType.added) { final source = (querySnapshot.metadata.isFromCache) ? "local cache" : "server"; print("Data fetched from $source"); } } }); ``` ```dart // Disable/enable network db.disableNetwork().then((_) { // Do offline things }); db.enableNetwork().then((_) { // Back online }); ``` -------------------------------- ### Enable Offline Access and Detect Connection State in Flutter Source: https://context7.com/firebase/snippets-flutter/llms.txt Configure Firebase Realtime Database for offline data access and detect the connection state. This ensures your app remains responsive even with intermittent network connectivity. ```dart // Keep data synced for offline access final scoresRef = FirebaseDatabase.instance.ref("scores"); scoresRef.keepSynced(true); // Detect connection state final connectedRef = FirebaseDatabase.instance.ref(".info/connected"); connectedRef.onValue.listen((event) { final connected = event.snapshot.value as bool? ?? false; if (connected) { print("Connected to Firebase"); } else { print("Disconnected from Firebase"); } }); // Set data on disconnect final presenceRef = FirebaseDatabase.instance.ref('disconnectmessage'); presenceRef.onDisconnect().set('I disconnected!'); // Full presence system final myConnectionsRef = FirebaseDatabase.instance.ref("users/joe/connections"); final lastOnlineRef = FirebaseDatabase.instance.ref("/users/joe/lastOnline"); final connectedRef2 = FirebaseDatabase.instance.ref(".info/connected"); connectedRef2.onValue.listen((event) { final connected = event.snapshot.value as bool? ?? false; if (connected) { final con = myConnectionsRef.push(); con.onDisconnect().remove(); lastOnlineRef.onDisconnect().set(ServerValue.timestamp); con.set(true); } }); // Server timestamps final userLastOnlineRef = FirebaseDatabase.instance.ref("users/joe/lastOnline"); userLastOnlineRef.onDisconnect().set(ServerValue.timestamp); // Clock skew detection final offsetRef = FirebaseDatabase.instance.ref(".info/serverTimeOffset"); offsetRef.onValue.listen((event) { final offset = event.snapshot.value as num? ?? 0.0; final estimatedServerTimeMs = DateTime.now().millisecondsSinceEpoch + offset; }); ``` -------------------------------- ### Perform Collection Group Queries in Dart Source: https://context7.com/firebase/snippets-flutter/llms.txt Query across all subcollections with the same name, regardless of their parent document. This is useful for querying data like 'reviews' or 'posts' that might exist in many different user profiles. ```dart db.collectionGroup("landmarks") .where("type", isEqualTo: "museum") .get(); ``` -------------------------------- ### Perform Multiple Aggregations in Dart Source: https://context7.com/firebase/snippets-flutter/llms.txt Execute multiple aggregations (count, sum, average) in a single query for efficiency. This allows you to retrieve various aggregate statistics simultaneously. ```dart db.collection("cities") .aggregate( count(), sum("population"), average("population"), ) .get() .then((res) { print(res.count); print(res.getSum("population")); print(res.getAverage("population")); }); ``` -------------------------------- ### Perform Average Aggregation in Dart Source: https://context7.com/firebase/snippets-flutter/llms.txt Calculate the average of a specific field across documents in a collection using the aggregate() method with average(). This is useful for finding average values. ```dart db.collection("cities").aggregate(average("population")).get().then( (res) => print(res.getAverage("population")), ); ``` -------------------------------- ### Perform Sum Aggregation in Dart Source: https://context7.com/firebase/snippets-flutter/llms.txt Calculate the sum of a specific field across documents in a collection using the aggregate() method with sum(). This is useful for totaling numerical data. ```dart db.collection("cities").aggregate(sum("population")).get().then( (res) => print(res.getSum("population")), ); ``` -------------------------------- ### Re-authenticate User in Flutter Source: https://context7.com/firebase/snippets-flutter/llms.txt Use this snippet to re-authenticate a user before performing sensitive operations like changing passwords or deleting accounts. It requires the user's current email and password. ```dart try { final userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword( email: 'user@example.com', password: 'current.password', ); final credential = userCredential.credential!; await FirebaseAuth.instance.currentUser! .reauthenticateWithCredential(credential); // Now safe to perform sensitive operations } on FirebaseAuthException catch (e) { print("Re-authentication failed: $e"); } ``` -------------------------------- ### Update Specific Fields in Documents Source: https://context7.com/firebase/snippets-flutter/llms.txt Update specific fields in documents without overwriting the entire document. Supports nested field updates, array operations, and atomic increments. ```dart // Update a single field final washingtonRef = db.collection("cites").doc("DC"); washingtonRef.update({"capital": true}).then( (value) => print("DocumentSnapshot successfully updated!"), onError: (e) => print("Error updating document $e")); ``` ```dart // Update nested fields using dot notation db.collection("users").doc("frank").update({ "age": 13, "favorites.color": "Red" }); ``` ```dart // Server timestamp final docRef = db.collection("objects").doc("some-id"); docRef.update({"timestamp": FieldValue.serverTimestamp()}); ``` ```dart // Atomically add/remove elements from arrays final washingtonRef2 = db.collection("cities").doc("DC"); washingtonRef2.update({ "regions": FieldValue.arrayUnion(["greater_virginia"]), }); washingtonRef2.update({ "regions": FieldValue.arrayRemove(["east_coast"]), }); ``` ```dart // Atomically increment a numeric value var washingtonRef3 = db.collection('cities').doc('DC'); washingtonRef3.update({"population": FieldValue.increment(50)}); ``` -------------------------------- ### Manage FCM Tokens in Flutter Source: https://context7.com/firebase/snippets-flutter/llms.txt Obtain the current Firebase Cloud Messaging (FCM) registration token and monitor for token refreshes. Send the token to your server to enable targeted push notifications. ```dart import 'package:firebase_messaging/firebase_messaging.dart'; // Get current registration token FirebaseMessaging.instance.getToken().then( (token) => print("FCM Token: $token"), onError: (e) => print("Error getting token: $e"), ); // Monitor token refresh FirebaseMessaging.instance.onTokenRefresh.listen((newToken) { print("Refreshed token: $newToken"); // Send to your server _sendRegistrationToServer(newToken); }); // Subscribe to topics FirebaseMessaging.instance.subscribeToTopic("weather"); ``` -------------------------------- ### Firestore Transactions and Batched Writes Source: https://context7.com/firebase/snippets-flutter/llms.txt Use transactions for atomic read-modify-write operations, or batched writes for multiple atomic writes. Transactions ensure data consistency by retrying if conflicts occur. ```dart // Transaction example final sfDocRef = db.collection("cities").doc("SF"); db.runTransaction((transaction) async { final snapshot = await transaction.get(sfDocRef); final newPopulation = snapshot.get("population") + 1; transaction.update(sfDocRef, {"population": newPopulation}); }).then( (value) => print("DocumentSnapshot successfully updated!"), onError: (e) => print("Error updating document $e"), ); ``` ```dart // Transaction returning a value db.runTransaction((transaction) { return transaction.get(sfDocRef).then((sfDoc) { final newPopulation = sfDoc.get("population") + 1; transaction.update(sfDocRef, {"population": newPopulation}); return newPopulation; }); }).then( (newPopulation) => print("Population increased to $newPopulation"), ); ``` ```dart // Batched writes final batch = db.batch(); var nycRef = db.collection("cities").doc("NYC"); batch.set(nycRef, {"name": "New York City"}); var sfRef = db.collection("cities").doc("SF"); batch.update(sfRef, {"population": 1000000}); var laRef = db.collection("cities").doc("LA"); batch.delete(laRef); // Commit the batch batch.commit().then((_) { print("Batch committed successfully"); }); ```