شما میتوانید با استفاده از متد onSnapshot() به یک سند گوش دهید . یک فراخوانی اولیه با استفاده از فراخوانی که شما ارائه میدهید، بلافاصله یک snapshot از سند با محتوای فعلی سند ایجاد میکند. سپس، هر بار که محتوا تغییر میکند، فراخوانی دیگری snapshot سند را بهروزرسانی میکند.
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()); });
سویفت
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)") }
هدف-سی
[[[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 که جریان snapshot 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(), ); }, ); } }
جاوا
پایتون
سی++
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; } });
نود جی اس
برو
پی اچ پی
// Not supported in the PHP client libraryوحدت
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)); } });
سی شارپ
روبی
رویدادهایی برای تغییرات محلی
نوشتنهای محلی در برنامه شما بلافاصله شنوندههای snapshot را فراخوانی میکنند. این به دلیل ویژگی مهمی به نام "جبران تأخیر" است. وقتی نوشتنی انجام میدهید، شنوندههای شما قبل از ارسال دادهها به backend، از دادههای جدید مطلع میشوند.
اسناد بازیابی شده دارای خاصیتی به metadata.hasPendingWrites هستند که نشان میدهد آیا سند دارای تغییرات محلی است که هنوز در backend نوشته نشدهاند یا خیر. میتوانید از این خاصیت برای تعیین منبع رویدادهای دریافت شده توسط snapshot listener خود استفاده کنید:
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()); });
سویفت
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() ?? [:])") }
هدف-سی
[[[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"), );
جاوا
# Not yet supported in the Java client library
پایتون
// Not yet supported in Python client library
سی++
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; } });
نود جی اس
// Not yet supported in the Node.js client libraryبرو
// Not yet supported in the Go client libraryپی اچ پی
// Not supported in the PHP client libraryوحدت
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}"); });
سی شارپ
// Not yet supported in the C# client libraryروبی
// Not yet supported in the Ruby client library
رویدادهای مربوط به تغییرات متادیتا
هنگام گوش دادن به تغییرات در یک سند، مجموعه یا پرس و جو، میتوانید گزینههایی را برای کنترل جزئیات رویدادهایی که شنونده شما دریافت خواهد کرد، ارسال کنید.
به طور پیشفرض، شنوندهها از تغییراتی که فقط بر ابرداده تأثیر میگذارند، مطلع نمیشوند. در نظر بگیرید وقتی برنامه شما یک سند جدید مینویسد چه اتفاقی میافتد:
- یک رویداد تغییر بلافاصله با دادههای جدید اجرا میشود. سند هنوز در backend نوشته نشده است، بنابراین پرچم "pending write"
trueاست. - سند در backend نوشته شده است.
- بخش مدیریت، کلاینت را از نوشتن موفقیتآمیز مطلع میکند. هیچ تغییری در دادههای سند ایجاد نشده است، اما به دلیل اینکه پرچم «در انتظار نوشتن» اکنون
falseاست، تغییری در فراداده رخ داده است.
اگر میخواهید هنگام تغییر ابرداده سند یا پرسوجو، رویدادهای snapshot را دریافت کنید، هنگام اتصال شنونده خود، یک شیء listen options ارسال کنید.
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) => { // ... });
سویفت
// Listen to document metadata. db.collection("cities").document("SF") .addSnapshotListener(includeMetadataChanges: true) { documentSnapshot, error in // ... }
هدف-سی
// 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) { // ... });
جاوا
// Not yet supported in the Java client libraryپایتون
// Not yet supported in Python client library
سی++
DocumentReference doc_ref = db->Collection("cities").Document("SF"); doc_ref.AddSnapshotListener( MetadataChanges::kInclude, [](const DocumentSnapshot& snapshot, Error error, const std::string& errorMsg) { /* ... */ });
نود جی اس
// Not yet supported the Node.js client libraryبرو
// Not yet supported in the Go client libraryپی اچ پی
// Not supported in the PHP client libraryوحدت
DocumentReference docRef = db.Collection("cities").Document("SF"); docRef.Listen(MetadataChanges.Include, snapshot => { // ... });
سی شارپ
// Not yet supported in the C# client libraryروبی
// Not yet supported in the Ruby client library
پیکربندی شنوندهها فقط برای تغییرات محلی
شنوندگان اسنپشات Cloud Firestore یک اسنپشات اولیه از حافظه پنهان محلی میگیرند و همزمان دادههای مربوطه را از سرور دریافت میکنند.
در برخی موارد، ممکن است نخواهید واکشیهای بعدی از سرور انجام شود. SDKهای کلاینت به شما این امکان را میدهند که شنوندهها را طوری پیکربندی کنید که فقط با توجه به دادههای موجود در حافظه پنهان محلی اجرا شوند. این به شما کمک میکند از فراخوانیهای غیرضروری سرور و هزینههای آنها جلوگیری کنید و از حافظه پنهان سمت کلاینت که دادههای محلی و جهشها را منعکس میکند، بهره ببرید.
در اینجا، گزینههای snapshot در کد کلاینت تنظیم شدهاند تا فقط امکان گوش دادن به تغییرات محلی را فراهم کنند.
Web
const unsubscribe = onSnapshot( doc(db, "cities", "SF"), { includeMetadataChanges: true, source:'cache' }, (documentSnapshot) => {//…} );
Web
// Not yet supported in the Web namespaced API سویفت
// Set up listener options
let options = SnapshotListenOptions()
.withSource(ListenSource.cache)
.withIncludeMetadataChanges(true)
db.collection("cities").document("SF")
.addSnapshotListener(options: options) { documentSnapshot, error in
// ...
}
هدف-سی
// 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 library
جاوا
# Not yet supported in the Java client library
پایتون
// Not yet supported in Python client library
سی++
// Not yet supported in the C++ client libraryنود جی اس
// Not yet supported in the Node.js client libraryبرو
// Not yet supported in the Go client libraryپی اچ پی
// Not yet supported in the PHP client libraryوحدت
// Not yet supported in the Unity client libraryسی شارپ
// Not yet supported in the C# client libraryروبی
// Not yet supported in the Ruby client library
گوش دادن به چندین سند در یک مجموعه
همانند اسناد، میتوانید به جای get() از onSnapshot() برای گوش دادن به نتایج یک پرسوجو استفاده کنید. این یک تصویر لحظهای از پرسوجو ایجاد میکند. به عنوان مثال، برای گوش دادن به اسناد با وضعیت 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(", ")); });
سویفت
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)") }
هدف-سی
[[[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(", ")}"); });
جاوا
پایتون
سی++
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; } });
نود جی اس
برو
پی اچ پی
// Not supported in the PHP client libraryوحدت
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); } });
سی شارپ
روبی
هر بار که نتایج پرسوجو تغییر کند (یعنی وقتی یک سند اضافه، حذف یا اصلاح میشود)، کنترلکنندهی اسنپشات، یک اسنپشات پرسوجوی جدید دریافت میکند.
مشاهده تغییرات بین اسنپشاتها
اغلب مفید است که تغییرات واقعی نتایج پرسوجو را بین اسنپشاتهای پرسوجو مشاهده کنید، نه اینکه صرفاً از کل اسنپشات پرسوجو استفاده کنید. به عنوان مثال، ممکن است بخواهید همزمان با اضافه شدن، حذف شدن و تغییر اسناد، یک کش (cache) را حفظ کنید.
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()); } }); });
سویفت
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())") } } }
هدف-سی
[[[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; } } });
جاوا
سی++
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; } });
پایتون
نود جی اس
برو
پی اچ پی
// Not supported in the PHP client libraryوحدت
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)); } } });
سی شارپ
روبی
وضعیت اولیه میتواند مستقیماً از سرور یا از یک حافظه پنهان محلی دریافت شود. اگر وضعیتی در حافظه پنهان محلی موجود باشد، تصویر لحظهای پرسوجو در ابتدا با دادههای ذخیرهشده پر میشود و سپس هنگامی که کلاینت به وضعیت سرور دسترسی پیدا کرد، با دادههای سرور بهروزرسانی میشود.
جدا کردن یک شنونده
وقتی دیگر علاقهای به گوش دادن به دادههای خود ندارید، باید شنونده خود را جدا کنید تا فراخوانی رویدادهای برگشتی شما متوقف شود. این به کلاینت اجازه میدهد تا استفاده از پهنای باند برای دریافت بهروزرسانیها را متوقف کند. برای مثال:
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();
سویفت
let listener = db.collection("cities").addSnapshotListener { querySnapshot, error in // ... } // ... // Stop listening to changes listener.remove()
هدف-سی
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();
جاوا
پایتون
سی++
// 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();
نود جی اس
برو
پی اچ پی
// Not supported in the PHP client libraryوحدت
listener.Stop();
سی شارپ
روبی
مدیریت خطاهای شنیداری
ممکن است گاهی اوقات شنود با شکست مواجه شود - برای مثال، به دلیل مجوزهای امنیتی، یا اگر سعی کردهاید به یک پرسوجوی نامعتبر گوش دهید. (درباره پرسوجوهای معتبر و نامعتبر بیشتر بدانید.) برای مدیریت این شکستها، میتوانید هنگام اتصال شنودگر snapshot خود، یک callback خطا ارائه دهید. پس از یک خطا، شنودگر دیگر هیچ رویدادی را دریافت نمیکند و نیازی به جدا کردن شنودگر شما نیست.
Web
import { collection, onSnapshot } from "firebase/firestore"; const unsubscribe = onSnapshot( collection(db, "cities"), (snapshot) => { // ... }, (error) => { // ... });
Web
db.collection("cities") .onSnapshot((snapshot) => { // ... }, (error) => { // ... });
سویفت
db.collection("cities") .addSnapshotListener { querySnapshot, error in if let error = error { print("Error retreiving collection: \(error)") } }
هدف-سی
[[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"), );
جاوا
پایتون
// Snippet coming soon
سی++
// Snippet coming soon.نود جی اس
برو
پی اچ پی
// Not supported in the PHP client libraryوحدت
ListenerRegistration registration = db.Collection("cities").Listen( querySnapshot => { // ... }); registration.ListenerTask.ContinueWithOnMainThread( listenerTask => { if (listenerTask.IsFaulted) { Debug.LogError($"Listen failed: {listenerTask.Exception}"); // ... // Handle the listener error. // ... } });
سی شارپ
// Snippet coming soonروبی
قدم بعدی چیست؟
- شنوندهها را با کوئریهای ساده و مرکب ترکیب کنید .
- اسناد بازیابی شده را مرتب و محدود کنید .
- صورتحساب برای شنوندگان را درک کنید .