קבלת עדכונים בזמן אמת
אפשר להאזין למסמך באמצעות השיטה onSnapshot(). קריאה ראשונית באמצעות הקריאה החוזרת שסיפקתם יוצרת תמונת מצב של המסמך באופן מיידי עם התוכן הנוכחי של המסמך היחיד. לאחר מכן, בכל פעם שהתוכן משתנה, מתבצעת קריאה נוספת לעדכון ה-snapshot של המסמך.
גרסה 9 לאינטרנט
import { doc, onSnapshot } from "firebase/firestore"; const unsub = onSnapshot(doc(db, "cities", "SF"), (doc) => { console.log("Current data: ", doc.data()); });
גרסה 8 לאינטרנט
db.collection("cities").doc("SF") .onSnapshot((doc) => { console.log("Current data: ", doc.data()); });
Swift
db.collection("cities").document("SF") .addSnapshotListener { documentSnapshot, error in guard let document = documentSnapshot else { print("Error fetching document: \(error!)") return } guard let data = document.data() else { print("Document data was empty.") return } print("Current data: \(data)") }
Objective-C
[[[self.db collectionWithPath:@"cities"] documentWithPath:@"SF"] addSnapshotListener:^(FIRDocumentSnapshot *snapshot, NSError *error) { if (snapshot == nil) { NSLog(@"Error fetching document: %@", error); return; } NSLog(@"Current data: %@", snapshot.data); }];
Kotlin
Android
val docRef = db.collection("cities").document("SF") docRef.addSnapshotListener { snapshot, e -> if (e != null) { Log.w(TAG, "Listen failed.", e) return@addSnapshotListener } if (snapshot != null && snapshot.exists()) { Log.d(TAG, "Current data: ${snapshot.data}") } else { Log.d(TAG, "Current data: null") } }
Java
Android
final DocumentReference docRef = db.collection("cities").document("SF"); docRef.addSnapshotListener(new EventListener<DocumentSnapshot>() { @Override public void onEvent(@Nullable DocumentSnapshot snapshot, @Nullable FirebaseFirestoreException e) { if (e != null) { Log.w(TAG, "Listen failed.", e); return; } if (snapshot != null && snapshot.exists()) { Log.d(TAG, "Current data: " + snapshot.getData()); } else { Log.d(TAG, "Current data: null"); } } });
Dart
final docRef = db.collection("cities").doc("SF"); docRef.snapshots().listen( (event) => print("current data: ${event.data()}"), onError: (error) => print("Listen failed: $error"), );
לרוב, רוצים שהממשק ישתנה בתגובה לשינויים בתוכן של מסמך או אוסף ב-Firestore. אפשר לעשות זאת באמצעות ווידג'ט StreamBuilder
שמשתמש בסטרימינג של תמונת המצב של Firestore:
class UserInformation extends StatefulWidget { @override _UserInformationState createState() => _UserInformationState(); } class _UserInformationState extends State<UserInformation> { final Stream<QuerySnapshot> _usersStream = FirebaseFirestore.instance.collection('users').snapshots(); @override Widget build(BuildContext context) { return StreamBuilder<QuerySnapshot>( stream: _usersStream, builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) { if (snapshot.hasError) { return const Text('Something went wrong'); } if (snapshot.connectionState == ConnectionState.waiting) { return const Text("Loading"); } return ListView( children: snapshot.data!.docs .map((DocumentSnapshot document) { Map<String, dynamic> data = document.data()! as Map<String, dynamic>; return ListTile( title: Text(data['full_name']), subtitle: Text(data['company']), ); }) .toList() .cast(), ); }, ); } }
Java
Python
C++
DocumentReference doc_ref = db->Collection("cities").Document("SF"); doc_ref.AddSnapshotListener( [](const DocumentSnapshot& snapshot, Error error, const std::string& errorMsg) { if (error == Error::kErrorOk) { if (snapshot.exists()) { std::cout << "Current data: " << snapshot << std::endl; } else { std::cout << "Current data: null" << std::endl; } } else { std::cout << "Listen failed: " << error << std::endl; } });
Node.js
המשך
PHP
// Not supported in the PHP client libraryUnity
DocumentReference docRef = db.Collection("cities").Document("SF"); docRef.Listen(snapshot => { Debug.Log("Callback received document snapshot."); Debug.Log(String.Format("Document data for {0} document:", snapshot.Id)); Dictionary<string, object> city = snapshot.ToDictionary(); foreach (KeyValuePair<string, object> pair in city) { Debug.Log(String.Format("{0}: {1}", pair.Key, pair.Value)); } });
C#
Ruby
אירועים של שינויים מקומיים
פעולות כתיבה מקומיות באפליקציה יפעילו מיד מאזינים של תמונות מצב. הסיבה לכך היא תכונה חשובה שנקראת 'פיצוי על זמן אחזור'. כשמבצעים פעולת כתיבה, המאזינים מקבלים הודעה עם הנתונים החדשים לפני שהנתונים נשלחים אל ה-Backend.
למסמכים שאוחזרו יש מאפיין metadata.hasPendingWrites שמציין אם בוצעו במסמך שינויים מקומיים שעדיין לא נכתבו בקצה העורפי. אתם יכולים להשתמש במאפיין הזה כדי לקבוע את המקור של האירועים שמתקבלים על ידי ה-listener של תמונת המצב:
גרסה 9 לאינטרנט
import { doc, onSnapshot } from "firebase/firestore"; const unsub = onSnapshot(doc(db, "cities", "SF"), (doc) => { const source = doc.metadata.hasPendingWrites ? "Local" : "Server"; console.log(source, " data: ", doc.data()); });
גרסה 8 לאינטרנט
db.collection("cities").doc("SF") .onSnapshot((doc) => { var source = doc.metadata.hasPendingWrites ? "Local" : "Server"; console.log(source, " data: ", doc.data()); });
Swift
db.collection("cities").document("SF") .addSnapshotListener { documentSnapshot, error in guard let document = documentSnapshot else { print("Error fetching document: \(error!)") return } let source = document.metadata.hasPendingWrites ? "Local" : "Server" print("\(source) data: \(document.data() ?? [:])") }
Objective-C
[[[self.db collectionWithPath:@"cities"] documentWithPath:@"SF"] addSnapshotListener:^(FIRDocumentSnapshot *snapshot, NSError *error) { if (snapshot == nil) { NSLog(@"Error fetching document: %@", error); return; } NSString *source = snapshot.metadata.hasPendingWrites ? @"Local" : @"Server"; NSLog(@"%@ data: %@", source, snapshot.data); }];
Kotlin
Android
val docRef = db.collection("cities").document("SF") docRef.addSnapshotListener { snapshot, e -> if (e != null) { Log.w(TAG, "Listen failed.", e) return@addSnapshotListener } val source = if (snapshot != null && snapshot.metadata.hasPendingWrites()) { "Local" } else { "Server" } if (snapshot != null && snapshot.exists()) { Log.d(TAG, "$source data: ${snapshot.data}") } else { Log.d(TAG, "$source data: null") } }
Java
Android
final DocumentReference docRef = db.collection("cities").document("SF"); docRef.addSnapshotListener(new EventListener<DocumentSnapshot>() { @Override public void onEvent(@Nullable DocumentSnapshot snapshot, @Nullable FirebaseFirestoreException e) { if (e != null) { Log.w(TAG, "Listen failed.", e); return; } String source = snapshot != null && snapshot.getMetadata().hasPendingWrites() ? "Local" : "Server"; if (snapshot != null && snapshot.exists()) { Log.d(TAG, source + " data: " + snapshot.getData()); } else { Log.d(TAG, source + " data: null"); } } });
Dart
final docRef = db.collection("cities").doc("SF"); docRef.snapshots().listen( (event) { final source = (event.metadata.hasPendingWrites) ? "Local" : "Server"; print("$source data: ${event.data()}"); }, onError: (error) => print("Listen failed: $error"), );
Java
# Not yet supported in the Java client library
Python
// Not yet supported in Python client library
C++
DocumentReference doc_ref = db->Collection("cities").Document("SF"); doc_ref.AddSnapshotListener([](const DocumentSnapshot& snapshot, Error error, const std::string& errorMsg) { if (error == Error::kErrorOk) { const char* source = snapshot.metadata().has_pending_writes() ? "Local" : "Server"; if (snapshot.exists()) { std::cout << source << " data: " << snapshot.Get("name").string_value() << std::endl; } else { std::cout << source << " data: null" << std::endl; } } else { std::cout << "Listen failed: " << error << std::endl; } });
Node.js
// Not yet supported in the Node.js client libraryהמשך
// Not yet supported in the Go client libraryPHP
// Not supported in the PHP client libraryUnity
DocumentReference docRef = db.Collection("cities").Document("SF"); docRef.Listen( snapshot => { string source = (snapshot != null && snapshot.Metadata.HasPendingWrites) ? "Local" : "Server"; string snapshotData = "null"; if (snapshot != null && snapshot.Exists) { System.Text.StringBuilder builder = new System.Text.StringBuilder(); IDictionary<string, object> dict = snapshot.ToDictionary(); foreach (var KVPair in dict) { builder.Append($"{KVPair.Key}: {KVPair.Value}\n"); } snapshotData = builder.ToString(); } Debug.Log($"{source} data: ${snapshotData}"); });
C#
// Not yet supported in the C# client libraryRuby
// Not yet supported in the Ruby client library
אירועים של שינויים במטא-נתונים
כשמקשיבים לשינויים במסמך, באוסף או בשאילתה, אפשר להעביר אפשרויות כדי לשלוט בגרנולריות של האירועים שה-listener יקבל.
כברירת מחדל, מאזינים לא מקבלים הודעה על שינויים שמשפיעים רק על מטא נתונים. כדאי לחשוב מה קורה כשהאפליקציה כותבת מסמך חדש:
- אירוע שינוי מופעל באופן מיידי עם הנתונים החדשים. המסמך עדיין לא נכתב אל ה-backend, ולכן הדגל 'pending writes' הוא
true. - המסמך נכתב בקצה העורפי.
- הקצה העורפי שולח ללקוח הודעה על הכתיבה המוצלחת. אין שינוי בנתוני המסמך, אבל יש שינוי במטא-נתונים כי הדגל 'כתיבות בהמתנה' הוא עכשיו
false.
אם רוצים לקבל אירועי תמונת מצב כשמשתנים המטא-נתונים של המסמך או השאילתה, צריך להעביר אובייקט של אפשרויות האזנה כשמצרפים את ה-listener.
גרסה 9 לאינטרנט
import { doc, onSnapshot } from "firebase/firestore"; const unsub = onSnapshot( doc(db, "cities", "SF"), { includeMetadataChanges: true }, (doc) => { // ... });
גרסה 8 לאינטרנט
db.collection("cities").doc("SF") .onSnapshot({ // Listen for document metadata changes includeMetadataChanges: true }, (doc) => { // ... });
Swift
// Listen to document metadata. db.collection("cities").document("SF") .addSnapshotListener(includeMetadataChanges: true) { documentSnapshot, error in // ... }
Objective-C
// Listen for metadata changes. [[[self.db collectionWithPath:@"cities"] documentWithPath:@"SF"] addSnapshotListenerWithIncludeMetadataChanges:YES listener:^(FIRDocumentSnapshot *snapshot, NSError *error) { // ... }];
Kotlin
Android
// Listen for metadata changes to the document. val docRef = db.collection("cities").document("SF") docRef.addSnapshotListener(MetadataChanges.INCLUDE) { snapshot, e -> // ... }
Java
Android
// Listen for metadata changes to the document. DocumentReference docRef = db.collection("cities").document("SF"); docRef.addSnapshotListener(MetadataChanges.INCLUDE, new EventListener<DocumentSnapshot>() { @Override public void onEvent(@Nullable DocumentSnapshot snapshot, @Nullable FirebaseFirestoreException e) { // ... } });
Dart
final docRef = db.collection("cities").doc("SF"); docRef.snapshots(includeMetadataChanges: true).listen((event) { // ... });
Java
// Not yet supported in the Java client libraryPython
// Not yet supported in Python client library
C++
DocumentReference doc_ref = db->Collection("cities").Document("SF"); doc_ref.AddSnapshotListener( MetadataChanges::kInclude, [](const DocumentSnapshot& snapshot, Error error, const std::string& errorMsg) { /* ... */ });
Node.js
// Not yet supported the Node.js client libraryהמשך
// Not yet supported in the Go client libraryPHP
// Not supported in the PHP client libraryUnity
DocumentReference docRef = db.Collection("cities").Document("SF"); docRef.Listen(MetadataChanges.Include, snapshot => { // ... });
C#
// Not yet supported in the C# client libraryRuby
// Not yet supported in the Ruby client library
הגדרת מאזינים לשינויים מקומיים בלבד
מאזינים לתמונת מצב של Firestore במצב Native יוצרים תמונת מצב ראשונית מהמטמון המקומי, ובמקביל מאחזרים נתונים תואמים מהשרת.
במקרים מסוימים, יכול להיות שלא תרצו לבצע אחזורים חוזרים מהשרת. ערכות SDK של לקוח מאפשרות להגדיר מאזינים שיפעלו רק ביחס לנתונים במטמון המקומי. כך תוכלו להימנע משיחות שרת מיותרות ומהעלויות שלהן, ולנצל את היתרונות של מטמון בצד הלקוח, שמשקף נתונים מחנויות מקומיות ופעולות לשינוי נתונים.
כאן, אפשרויות הצילום של התמונה מוגדרות בקוד הלקוח כדי לאפשר האזנה רק לשינויים מקומיים.
גרסה 9 לאינטרנט
const unsubscribe = onSnapshot( doc(db, "cities", "SF"), { includeMetadataChanges: true, source:'cache' }, (documentSnapshot) => {//…} );
גרסה 8 לאינטרנט
// Not yet supported in the Web namespaced APISwift
// Set up listener options let options = SnapshotListenOptions() .withSource(ListenSource.cache) .withIncludeMetadataChanges(true) db.collection("cities").document("SF") .addSnapshotListener(options: options) { documentSnapshot, error in // ... }
Objective-C
// Set up listener options FIRSnapshotListenOptions *options = [[FIRSnapshotListenOptions alloc] init]; FIRSnapshotListenOptions *optionsWithSourceAndMetadata = [[options optionsWithIncludeMetadataChanges:YES] optionsWithSource:FIRListenSourceCache]; [[[self.db collectionWithPath:@"cities"] documentWithPath:@"SF"] addSnapshotListenerWithOptions:optionsWithSourceAndMetadata listener: ^ (FIRDocumentSnapshot * snapshot, NSError * error) { //… } ];
Kotlin
Android
// Set up listener options val options = SnapshotListenOptions.Builder() .setMetadataChanges(MetadataChanges.INCLUDE) .setSource(ListenSource.CACHE) .build(); db.collection("cities").document("SF") .addSnapshotListener(options) { snapshot, error -> //… }
Java
Android
// Set up listener options SnapshotListenOptions options = new SnapshotListenOptions.Builder() .setMetadataChanges(MetadataChanges.INCLUDE) .setSource(ListenSource.CACHE) .build(); db.collection("cities").document("SF").addSnapshotListener(options, new EventListener<DocumentSnapshot>() { //… });
Dart
// Not yet supported in this client libraryJava
# Not yet supported in the Java client library
Python
// Not yet supported in Python client library
C++
// Not yet supported in the C++ client libraryNode.js
// Not yet supported in the Node.js client libraryהמשך
// Not yet supported in the Go client libraryPHP
// Not yet supported in the PHP client libraryUnity
// Not yet supported in the Unity client libraryC#
// Not yet supported in the C# client libraryRuby
// Not yet supported in the Ruby client library
האזנה למספר מסמכים באוסף
בדומה למסמכים, אפשר להשתמש ב-onSnapshot() במקום ב-get() כדי להאזין לתוצאות של שאילתה. הפעולה הזו יוצרת snapshot של השאילתה. לדוגמה, כדי להאזין למסמכים עם המצב CA:
גרסה 9 לאינטרנט
import { collection, query, where, onSnapshot } from "firebase/firestore"; const q = query(collection(db, "cities"), where("state", "==", "CA")); const unsubscribe = onSnapshot(q, (querySnapshot) => { const cities = []; querySnapshot.forEach((doc) => { cities.push(doc.data().name); }); console.log("Current cities in CA: ", cities.join(", ")); });
גרסה 8 לאינטרנט
db.collection("cities").where("state", "==", "CA") .onSnapshot((querySnapshot) => { var cities = []; querySnapshot.forEach((doc) => { cities.push(doc.data().name); }); console.log("Current cities in CA: ", cities.join(", ")); });
Swift
db.collection("cities").whereField("state", isEqualTo: "CA") .addSnapshotListener { querySnapshot, error in guard let documents = querySnapshot?.documents else { print("Error fetching documents: \(error!)") return } let cities = documents.compactMap { $0["name"] } print("Current cities in CA: \(cities)") }
Objective-C
[[[self.db collectionWithPath:@"cities"] queryWhereField:@"state" isEqualTo:@"CA"] addSnapshotListener:^(FIRQuerySnapshot *snapshot, NSError *error) { if (snapshot == nil) { NSLog(@"Error fetching documents: %@", error); return; } NSMutableArray *cities = [NSMutableArray array]; for (FIRDocumentSnapshot *document in snapshot.documents) { [cities addObject:document.data[@"name"]]; } NSLog(@"Current cities in CA: %@", cities); }];
Kotlin
Android
db.collection("cities") .whereEqualTo("state", "CA") .addSnapshotListener { value, e -> if (e != null) { Log.w(TAG, "Listen failed.", e) return@addSnapshotListener } val cities = ArrayList<String>() for (doc in value!!) { doc.getString("name")?.let { cities.add(it) } } Log.d(TAG, "Current cites in CA: $cities") }
Java
Android
db.collection("cities") .whereEqualTo("state", "CA") .addSnapshotListener(new EventListener<QuerySnapshot>() { @Override public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException e) { if (e != null) { Log.w(TAG, "Listen failed.", e); return; } List<String> cities = new ArrayList<>(); for (QueryDocumentSnapshot doc : value) { if (doc.get("name") != null) { cities.add(doc.getString("name")); } } Log.d(TAG, "Current cites in CA: " + cities); } });
Dart
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(", ")}"); });
Java
Python
C++
db->Collection("cities") .WhereEqualTo("state", FieldValue::String("CA")) .AddSnapshotListener([](const QuerySnapshot& snapshot, Error error, const std::string& errorMsg) { if (error == Error::kErrorOk) { std::vector<std::string> cities; std::cout << "Current cities in CA: " << error << std::endl; for (const DocumentSnapshot& doc : snapshot.documents()) { cities.push_back(doc.Get("name").string_value()); std::cout << "" << cities.back() << std::endl; } } else { std::cout << "Listen failed: " << error << std::endl; } });
Node.js
המשך
PHP
// Not supported in the PHP client libraryUnity
Query query = db.Collection("cities").WhereEqualTo("State", "CA"); ListenerRegistration listener = query.Listen(snapshot => { Debug.Log("Callback received query snapshot."); Debug.Log("Current cities in California:"); foreach (DocumentSnapshot documentSnapshot in snapshot.Documents) { Debug.Log(documentSnapshot.Id); } });
C#
Ruby
ה-handler של התמונה יקבל תמונה חדשה של השאילתה בכל פעם שתוצאות השאילתה ישתנו (כלומר, כשמסמך יתווסף, יוסר או ישונה).
צפייה בשינויים בין תמונות מצב
לעתים קרובות כדאי לראות את השינויים בפועל בתוצאות של שאילתה בין תמונות מצב של שאילתה, במקום להשתמש פשוט בתמונת המצב של השאילתה כולה. לדוגמה, יכול להיות שתרצו לשמור מטמון כשמוסיפים, מסירים ומשנים מסמכים.
גרסה 9 לאינטרנט
import { collection, query, where, onSnapshot } from "firebase/firestore"; const q = query(collection(db, "cities"), where("state", "==", "CA")); const unsubscribe = onSnapshot(q, (snapshot) => { snapshot.docChanges().forEach((change) => { if (change.type === "added") { console.log("New city: ", change.doc.data()); } if (change.type === "modified") { console.log("Modified city: ", change.doc.data()); } if (change.type === "removed") { console.log("Removed city: ", change.doc.data()); } }); });
גרסה 8 לאינטרנט
db.collection("cities").where("state", "==", "CA") .onSnapshot((snapshot) => { snapshot.docChanges().forEach((change) => { if (change.type === "added") { console.log("New city: ", change.doc.data()); } if (change.type === "modified") { console.log("Modified city: ", change.doc.data()); } if (change.type === "removed") { console.log("Removed city: ", change.doc.data()); } }); });
Swift
db.collection("cities").whereField("state", isEqualTo: "CA") .addSnapshotListener { querySnapshot, error in guard let snapshot = querySnapshot else { print("Error fetching snapshots: \(error!)") return } snapshot.documentChanges.forEach { diff in if (diff.type == .added) { print("New city: \(diff.document.data())") } if (diff.type == .modified) { print("Modified city: \(diff.document.data())") } if (diff.type == .removed) { print("Removed city: \(diff.document.data())") } } }
Objective-C
[[[self.db collectionWithPath:@"cities"] queryWhereField:@"state" isEqualTo:@"CA"] addSnapshotListener:^(FIRQuerySnapshot *snapshot, NSError *error) { if (snapshot == nil) { NSLog(@"Error fetching documents: %@", error); return; } for (FIRDocumentChange *diff in snapshot.documentChanges) { if (diff.type == FIRDocumentChangeTypeAdded) { NSLog(@"New city: %@", diff.document.data); } if (diff.type == FIRDocumentChangeTypeModified) { NSLog(@"Modified city: %@", diff.document.data); } if (diff.type == FIRDocumentChangeTypeRemoved) { NSLog(@"Removed city: %@", diff.document.data); } } }];
Kotlin
Android
db.collection("cities") .whereEqualTo("state", "CA") .addSnapshotListener { snapshots, e -> if (e != null) { Log.w(TAG, "listen:error", e) return@addSnapshotListener } for (dc in snapshots!!.documentChanges) { when (dc.type) { DocumentChange.Type.ADDED -> Log.d(TAG, "New city: ${dc.document.data}") DocumentChange.Type.MODIFIED -> Log.d(TAG, "Modified city: ${dc.document.data}") DocumentChange.Type.REMOVED -> Log.d(TAG, "Removed city: ${dc.document.data}") } } }
Java
Android
db.collection("cities") .whereEqualTo("state", "CA") .addSnapshotListener(new EventListener<QuerySnapshot>() { @Override public void onEvent(@Nullable QuerySnapshot snapshots, @Nullable FirebaseFirestoreException e) { if (e != null) { Log.w(TAG, "listen:error", e); return; } for (DocumentChange dc : snapshots.getDocumentChanges()) { switch (dc.getType()) { case ADDED: Log.d(TAG, "New city: " + dc.getDocument().getData()); break; case MODIFIED: Log.d(TAG, "Modified city: " + dc.getDocument().getData()); break; case REMOVED: Log.d(TAG, "Removed city: " + dc.getDocument().getData()); break; } } } });
Dart
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; } } });
Java
C++
db->Collection("cities") .WhereEqualTo("state", FieldValue::String("CA")) .AddSnapshotListener([](const QuerySnapshot& snapshot, Error error, const std::string& errorMsg) { if (error == Error::kErrorOk) { for (const DocumentChange& dc : snapshot.DocumentChanges()) { switch (dc.type()) { case DocumentChange::Type::kAdded: std::cout << "New city: " << dc.document().Get("name").string_value() << std::endl; break; case DocumentChange::Type::kModified: std::cout << "Modified city: " << dc.document().Get("name").string_value() << std::endl; break; case DocumentChange::Type::kRemoved: std::cout << "Removed city: " << dc.document().Get("name").string_value() << std::endl; break; } } } else { std::cout << "Listen failed: " << error << std::endl; } });
Python
Node.js
המשך
PHP
// Not supported in the PHP client libraryUnity
Query query = db.Collection("cities").WhereEqualTo("State", "CA"); ListenerRegistration listener = query.Listen(snapshot => { foreach (DocumentChange change in snapshot.GetChanges()) { if (change.ChangeType == DocumentChange.Type.Added) { Debug.Log(String.Format("New city: {0}", change.Document.Id)); } else if (change.ChangeType == DocumentChange.Type.Modified) { Debug.Log(String.Format("Modified city: {0}", change.Document.Id)); } else if (change.ChangeType == DocumentChange.Type.Removed) { Debug.Log(String.Format("Removed city: {0}", change.Document.Id)); } } });
C#
Ruby
המצב ההתחלתי יכול להגיע ישירות מהשרת או ממטמון מקומי. אם יש מצב זמין במטמון מקומי, התמונה של האילת תאוכלס בהתחלה בנתונים שבמטמון, ואז תתעדכן בנתונים של השרת כשהלקוח יתעדכן במצב של השרת.
ניתוק listener
כשאתם כבר לא רוצים להאזין לנתונים, אתם צריכים לנתק את ה-listener כדי שהקריאות החוזרות (callback) של האירועים יפסיקו להיקרא. כך הלקוח יכול להפסיק להשתמש ברוחב פס כדי לקבל עדכונים. לדוגמה:
גרסה 9 לאינטרנט
import { collection, onSnapshot } from "firebase/firestore"; const unsubscribe = onSnapshot(collection(db, "cities"), () => { // Respond to data // ... }); // Later ... // Stop listening to changes unsubscribe();
גרסה 8 לאינטרנט
var unsubscribe = db.collection("cities") .onSnapshot(() => { // Respond to data // ... }); // Later ... // Stop listening to changes unsubscribe();
Swift
let listener = db.collection("cities").addSnapshotListener { querySnapshot, error in // ... } // ... // Stop listening to changes listener.remove()
Objective-C
id<FIRListenerRegistration> listener = [[self.db collectionWithPath:@"cities"] addSnapshotListener:^(FIRQuerySnapshot *snapshot, NSError *error) { // ... }]; // ... // Stop listening to changes [listener remove];
Kotlin
Android
val query = db.collection("cities") val registration = query.addSnapshotListener { snapshots, e -> // ... } // ... // Stop listening to changes registration.remove()
Java
Android
Query query = db.collection("cities"); ListenerRegistration registration = query.addSnapshotListener( new EventListener<QuerySnapshot>() { // ... }); // ... // Stop listening to changes registration.remove();
Dart
final collection = db.collection("cities"); final listener = collection.snapshots().listen((event) { // ... }); listener.cancel();
Java
Python
C++
// Add a listener Query query = db->Collection("cities"); ListenerRegistration registration = query.AddSnapshotListener( [](const QuerySnapshot& snapshot, Error error, const std::string& errorMsg) { /* ... */ }); // Stop listening to changes registration.Remove();
Node.js
המשך
PHP
// Not supported in the PHP client libraryUnity
listener.Stop();
C#
Ruby
טיפול בשגיאות בהאזנה
יכול להיות שלפעמים ההאזנה תיכשל – למשל, בגלל הרשאות אבטחה, או אם ניסיתם להאזין לשאילתה לא תקינה. (מידע נוסף על שאילתות תקינות ופסולות) כדי לטפל בכשלים האלה, אפשר לספק פונקציית callback לשגיאה כשמצרפים את ה-listener של התמונה. אחרי שגיאה, ה-listener לא יקבל יותר אירועים, ואין צורך לנתק אותו.
גרסה 9 לאינטרנט
import { collection, onSnapshot } from "firebase/firestore"; const unsubscribe = onSnapshot( collection(db, "cities"), (snapshot) => { // ... }, (error) => { // ... });
גרסה 8 לאינטרנט
db.collection("cities") .onSnapshot((snapshot) => { // ... }, (error) => { // ... });
Swift
db.collection("cities") .addSnapshotListener { querySnapshot, error in if let error = error { print("Error retreiving collection: \(error)") } }
Objective-C
[[self.db collectionWithPath:@"cities"] addSnapshotListener:^(FIRQuerySnapshot *snapshot, NSError *error) { if (error != nil) { NSLog(@"Error retreving collection: %@", error); } }];
Kotlin
Android
db.collection("cities") .addSnapshotListener { snapshots, e -> if (e != null) { Log.w(TAG, "listen:error", e) return@addSnapshotListener } for (dc in snapshots!!.documentChanges) { if (dc.type == DocumentChange.Type.ADDED) { Log.d(TAG, "New city: ${dc.document.data}") } } }
Java
Android
db.collection("cities") .addSnapshotListener(new EventListener<QuerySnapshot>() { @Override public void onEvent(@Nullable QuerySnapshot snapshots, @Nullable FirebaseFirestoreException e) { if (e != null) { Log.w(TAG, "listen:error", e); return; } for (DocumentChange dc : snapshots.getDocumentChanges()) { if (dc.getType() == Type.ADDED) { Log.d(TAG, "New city: " + dc.getDocument().getData()); } } } });
Dart
final docRef = db.collection("cities"); docRef.snapshots().listen( (event) => print("listener attached"), onError: (error) => print("Listen failed: $error"), );
Java
Python
// Snippet coming soon
C++
// Snippet coming soon.Node.js
המשך
PHP
// Not supported in the PHP client libraryUnity
ListenerRegistration registration = db.Collection("cities").Listen( querySnapshot => { // ... }); registration.ListenerTask.ContinueWithOnMainThread( listenerTask => { if (listenerTask.IsFaulted) { Debug.LogError($"Listen failed: {listenerTask.Exception}"); // ... // Handle the listener error. // ... } });
C#
// Snippet coming soonRuby
תמחור
התמחור של פעולות מאזין בזמן אמת תלוי במהדורת מסד הנתונים. תוכלו לעיין במקורות המידע הבאים: