يمكنك الاستماع إلى مستند باستخدام طريقة onSnapshot(). يؤدي إجراء مكالمة أولية باستخدام دالة الاستدعاء التي تقدّمها إلى إنشاء لقطة للمستند على الفور مع المحتوى الحالي للمستند الواحد. بعد ذلك، في كل مرة تتغير فيها المحتويات، يقوم استدعاء آخر بتحديث لقطة المستند.
Web
import { doc, onSnapshot } from "firebase/firestore"; const unsub = onSnapshot(doc(db, "cities", "SF"), (doc) => { console.log("Current data: ", doc.data()); });
Web
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
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
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
أحداث التغييرات المحلية
ستستدعي عمليات الكتابة المحلية في تطبيقك مستمعي اللقطات على الفور. ويرجع ذلك إلى ميزة مهمة تُسمى "تعويض وقت الاستجابة". عند إجراء عملية كتابة، سيتم إعلام المستمعين بالبيانات الجديدة قبل إرسال البيانات إلى الخلفية.
تحتوي المستندات التي تم استردادها على سمة metadata.hasPendingWrites تشير إلى ما إذا كان المستند يتضمّن تغييرات محلية لم تتم كتابتها في الخلفية بعد. يمكنك استخدام هذه السمة لتحديد مصدر الأحداث التي يتلقّاها
مستمع اللقطات:
Web
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()); });
Web
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
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
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 libraryلغة Ruby
// Not yet supported in the Ruby client library
أحداث تغييرات البيانات الوصفية
عند الاستماع إلى التغييرات في مستند أو مجموعة أو طلب بحث، يمكنك تمرير الخيارات للتحكّم في دقة الأحداث التي سيتلقّاها المستمع.
وفقًا للإعدادات التلقائية، لا يتم إشعار المستمعين بالتغييرات التي تؤثر في البيانات الوصفية فقط. لنفترض أنّ تطبيقك يكتب مستندًا جديدًا:
- يتم تشغيل حدث تغيير على الفور باستخدام البيانات الجديدة. لم تتم كتابة المستند
في الخلفية بعد، لذا فإنّ علامة "الكتابات في انتظار المراجعة"
هي
true. - تتم كتابة المستند في الخلفية.
- تُرسل الخلفية إشعارًا إلى العميل بنجاح عملية الكتابة. لا يتم إجراء أي تغيير على بيانات المستند، ولكن يتم إجراء تغيير على البيانات الوصفية لأنّ علامة "عمليات الكتابة في انتظار المراجعة" أصبحت الآن
false.
إذا أردت تلقّي أحداث اللقطات عند تغيير البيانات الوصفية للمستند أو طلب البحث، يمكنك تمرير كائن خيارات الاستماع عند إرفاق المستمع.
Web
import { doc, onSnapshot } from "firebase/firestore"; const unsub = onSnapshot( doc(db, "cities", "SF"), { includeMetadataChanges: true }, (doc) => { // ... });
Web
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
// Listen for metadata changes to the document. val docRef = db.collection("cities").document("SF") docRef.addSnapshotListener(MetadataChanges.INCLUDE) { snapshot, e -> // ... }
Java
// 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 libraryلغة Ruby
// Not yet supported in the Ruby client library
ضبط المستمعين للتغييرات المحلية فقط
Cloud Firestore snapshot listeners take an initial snapshot from the local cache and concurrently fetch corresponding data from the server.
في بعض الحالات، قد لا تريد عمليات جلب متابعة من الخادم. تتيح لك حزم تطوير البرامج (SDK) للعملاء ضبط المستمعين ليتم تشغيلهم فقط فيما يتعلق بالبيانات الموجودة في ذاكرة التخزين المؤقت المحلية. يساعدك ذلك في تجنُّب طلبات الخادم غير الضرورية وتكاليفها، والاستفادة من ذاكرة التخزين المؤقت من جهة العميل التي تعكس البيانات المحلية والتغييرات.
هنا، يتم ضبط خيارات اللقطة في رمز العميل للسماح بالاستماع إلى التغييرات المحلية فقط.
Web
const unsubscribe = onSnapshot( doc(db, "cities", "SF"), { includeMetadataChanges: true, source:'cache' }, (documentSnapshot) => {//…} );
Web
// 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
// 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
// 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 library#C
// Not yet supported in the C# client libraryلغة Ruby
// Not yet supported in the Ruby client library
الاستماع إلى مستندات متعدّدة في مجموعة
كما هو الحال مع المستندات، يمكنك استخدام onSnapshot() بدلاً من get() للاستماع إلى
نتائج طلب البحث. يؤدي ذلك إلى إنشاء لقطة لطلب البحث. على سبيل المثال، للاستماع إلى
المستندات التي تتضمّن الحالة CA:
Web
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(", ")); });
Web
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
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
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
سيتلقّى معالج اللقطات لقطة جديدة لنتائج طلب البحث في كل مرة تتغيّر فيها نتائج طلب البحث (أي عند إضافة مستند أو إزالته أو تعديله).
عرض التغييرات بين اللقطات
غالبًا ما يكون من المفيد الاطّلاع على التغييرات الفعلية في نتائج طلب البحث بين لقطات طلب البحث، بدلاً من استخدام لقطة طلب البحث بالكامل. على سبيل المثال، قد ترغب في الاحتفاظ بذاكرة تخزين مؤقت عند إضافة المستندات الفردية وإزالتها وتعديلها.
Web
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()); } }); });
Web
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
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
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
يمكن أن تأتي الحالة الأولية من الخادم مباشرةً أو من ذاكرة تخزين مؤقت محلية. إذا كانت هناك حالة متاحة في ذاكرة تخزين مؤقت محلية، سيتم في البداية ملء لقطة طلب البحث بالبيانات المخزّنة مؤقتًا، ثم يتم تعديلها ببيانات الخادم عندما يطّلع العميل على حالة الخادم.
فصل مستمع
عندما لا تعود مهتمًا بالاستماع إلى بياناتك، عليك فصل المستمع حتى تتوقف عمليات استدعاء الأحداث. يتيح ذلك للعميل التوقف عن استخدام معدل نقل البيانات لتلقّي التحديثات. على سبيل المثال:
Web
import { collection, onSnapshot } from "firebase/firestore"; const unsubscribe = onSnapshot(collection(db, "cities"), () => { // Respond to data // ... }); // Later ... // Stop listening to changes unsubscribe();
Web
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
val query = db.collection("cities") val registration = query.addSnapshotListener { snapshots, e -> // ... } // ... // Stop listening to changes registration.remove()
Java
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
التعامل مع أخطاء الاستماع
قد يتعذّر الاستماع أحيانًا، على سبيل المثال، بسبب أذونات الأمان أو إذا حاولت الاستماع إلى طلب غير صالح. (مزيد من المعلومات عن طلبات البحث الصالحة وغير الصالحة) ولمعالجة حالات الفشل هذه، يمكنك تقديم دالة استدعاء للخطأ عند إرفاق مستمع اللقطة. بعد حدوث خطأ، لن يتلقّى المستمع أي أحداث أخرى، ولن تحتاج إلى فصل المستمع.
Web
import { collection, onSnapshot } from "firebase/firestore"; const unsubscribe = onSnapshot( collection(db, "cities"), (snapshot) => { // ... }, (error) => { // ... });
Web
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
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
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 soonلغة Ruby
الأسعار
تعتمد أسعار عمليات الاستماع في الوقت الفعلي على إصدار قاعدة البيانات. اطّلِع على ما يلي:
الخطوات التالية
- الجمع بين المستمعين وطلبات البحث البسيطة والمركّبة
- ترتيب المستندات التي تم استردادها وحصرها
- التعرّف على الفوترة للمستمعين