Bạn có thể nghe một tài liệu bằng phương thức onSnapshot()
. Một lệnh gọi ban đầu sử dụng lệnh gọi lại mà bạn cung cấp sẽ tạo ảnh chụp nhanh tài liệu ngay lập tức với nội dung hiện tại của tài liệu đơn lẻ. Sau đó, mỗi khi nội dung thay đổi, một cuộc gọi khác sẽ cập nhật ảnh chụp nhanh tài liệu.
Web version 9
import { doc, onSnapshot } from "firebase/firestore"; const unsub = onSnapshot(doc(db, "cities", "SF"), (doc) => { console.log("Current data: ", doc.data()); });
Web version 8
db.collection("cities").doc("SF") .onSnapshot((doc) => { console.log("Current data: ", doc.data()); });
Nhanh
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); }];
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"); } } });
Kotlin+KTX
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") } }
Dart
final docRef = db.collection("cities").doc("SF"); docRef.snapshots().listen( (event) => print("current data: ${event.data()}"), onError: (error) => print("Listen failed: $error"), );
Thông thường, bạn muốn giao diện người dùng của mình phản ứng với những thay đổi trong nội dung của tài liệu hoặc bộ sưu tập Firestore. Bạn có thể làm như vậy với tiện ích StreamBuilder
sử dụng luồng ảnh chụp nhanh 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
Đi
PHP
// Not supported in the PHP client library
Đoàn kết
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#
DocumentReference docRef = db.Collection("cities").Document("SF"); FirestoreChangeListener listener = docRef.Listen(snapshot => { Console.WriteLine("Callback received document snapshot."); Console.WriteLine("Document exists? {0}", snapshot.Exists); if (snapshot.Exists) { Console.WriteLine("Document data for {0} document:", snapshot.Id); Dictionary<string, object> city = snapshot.ToDictionary(); foreach (KeyValuePair<string, object> pair in city) { Console.WriteLine("{0}: {1}", pair.Key, pair.Value); } } });
Ruby
Sự kiện thay đổi cục bộ
Các bản ghi cục bộ trong ứng dụng của bạn sẽ gọi người nghe ảnh chụp nhanh ngay lập tức. Điều này là do một tính năng quan trọng được gọi là "bù độ trễ". Khi bạn thực hiện ghi, người nghe của bạn sẽ được thông báo về dữ liệu mới trước khi dữ liệu được gửi đến chương trình phụ trợ.
Các tài liệu đã truy xuất có thuộc tính metadata.hasPendingWrites
cho biết liệu tài liệu có các thay đổi cục bộ chưa được ghi vào chương trình phụ trợ hay không. Bạn có thể sử dụng thuộc tính này để xác định nguồn sự kiện mà trình nghe ảnh chụp nhanh của bạn nhận được:
Web version 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()); });
Web version 8
db.collection("cities").doc("SF") .onSnapshot((doc) => { var source = doc.metadata.hasPendingWrites ? "Local" : "Server"; console.log(source, " data: ", doc.data()); });
Nhanh
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); }];
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"); } } });
Kotlin+KTX
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") } }
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
Đi
// Not yet supported in the Go client library
PHP
// Not supported in the PHP client library
Đoàn kết
// Not yet supported in the Unity SDK
C#
// Not yet supported in the C# client library
Ruby
// Not yet supported in the Ruby client library
Sự kiện thay đổi siêu dữ liệu
Khi lắng nghe các thay đổi đối với tài liệu, bộ sưu tập hoặc truy vấn, bạn có thể chuyển các tùy chọn để kiểm soát mức độ chi tiết của các sự kiện mà người nghe của bạn sẽ nhận được.
Theo mặc định, người nghe không được thông báo về những thay đổi chỉ ảnh hưởng đến siêu dữ liệu. Xem xét điều gì sẽ xảy ra khi ứng dụng của bạn viết một tài liệu mới:
- Một sự kiện thay đổi ngay lập tức được kích hoạt với dữ liệu mới. Tài liệu vẫn chưa được ghi vào chương trình phụ trợ nên cờ "ghi đang chờ xử lý" là
true
. - Tài liệu được ghi vào chương trình phụ trợ.
- Phần phụ trợ thông báo cho khách hàng về việc ghi thành công. Không có thay đổi nào đối với dữ liệu tài liệu, nhưng có một thay đổi về siêu dữ liệu vì cờ "ghi đang chờ xử lý" hiện là
false
.
Nếu bạn muốn nhận các sự kiện chụp nhanh khi tài liệu hoặc siêu dữ liệu truy vấn thay đổi, hãy chuyển đối tượng tùy chọn lắng nghe khi đính kèm trình nghe của bạn:
Web version 9
import { doc, onSnapshot } from "firebase/firestore"; const unsub = onSnapshot( doc(db, "cities", "SF"), { includeMetadataChanges: true }, (doc) => { // ... });
Web version 8
db.collection("cities").doc("SF") .onSnapshot({ // Listen for document metadata changes includeMetadataChanges: true }, (doc) => { // ... });
Nhanh
// 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) { // ... }];
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) { // ... } });
Kotlin+KTX
// Listen for metadata changes to the document. val docRef = db.collection("cities").document("SF") docRef.addSnapshotListener(MetadataChanges.INCLUDE) { snapshot, e -> // ... }
Dart
final docRef = db.collection("cities").doc("SF"); docRef.snapshots(includeMetadataChanges: true).listen((event) { // ... });
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( MetadataChanges::kInclude, [](const DocumentSnapshot& snapshot, Error error, const std::string& errorMsg) { /* ... */ });
Node.js
// Not yet supported the Node.js client library
Đi
// Not yet supported in the Go client library
PHP
// Not supported in the PHP client library
Đoàn kết
// Not yet supported in the Unity SDK
C#
// Not yet supported in the C# client library
Ruby
// Not yet supported in the Ruby client library
Nghe nhiều tài liệu trong một bộ sưu tập
Đối với tài liệu, bạn có thể sử dụng onSnapshot()
thay vì get()
để nghe kết quả của một truy vấn. Điều này tạo ra một ảnh chụp nhanh truy vấn. Ví dụ: để nghe các tài liệu với CA
tiểu bang:
Web version 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(", ")); });
Web version 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(", ")); });
Nhanh
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.map { $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); }];
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); } });
Kotlin+KTX
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") }
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
Đi
PHP
// Not supported in the PHP client library
Đoàn kết
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#
CollectionReference citiesRef = db.Collection("cities"); Query query = db.Collection("cities").WhereEqualTo("State", "CA"); FirestoreChangeListener listener = query.Listen(snapshot => { Console.WriteLine("Callback received query snapshot."); Console.WriteLine("Current cities in California:"); foreach (DocumentSnapshot documentSnapshot in snapshot.Documents) { Console.WriteLine(documentSnapshot.Id); } });
Ruby
Trình xử lý ảnh chụp nhanh sẽ nhận được ảnh chụp nhanh truy vấn mới mỗi khi kết quả truy vấn thay đổi (nghĩa là khi một tài liệu được thêm, xóa hoặc sửa đổi).
Xem các thay đổi giữa các ảnh chụp nhanh
Thường sẽ hữu ích khi xem các thay đổi thực tế đối với kết quả truy vấn giữa các ảnh chụp nhanh truy vấn, thay vì chỉ sử dụng toàn bộ ảnh chụp nhanh truy vấn. Ví dụ: bạn có thể muốn duy trì bộ nhớ cache khi các tài liệu riêng lẻ được thêm, xóa và sửa đổi.
Web version 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()); } }); });
Web version 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()); } }); });
Nhanh
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); } } }];
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; } } } });
Kotlin+KTX
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}") } } }
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
Đi
PHP
// Not supported in the PHP client library
Đoàn kết
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#
CollectionReference citiesRef = db.Collection("cities"); Query query = db.Collection("cities").WhereEqualTo("State", "CA"); FirestoreChangeListener listener = query.Listen(snapshot => { foreach (DocumentChange change in snapshot.Changes) { if (change.ChangeType.ToString() == "Added") { Console.WriteLine("New city: {0}", change.Document.Id); } else if (change.ChangeType.ToString() == "Modified") { Console.WriteLine("Modified city: {0}", change.Document.Id); } else if (change.ChangeType.ToString() == "Removed") { Console.WriteLine("Removed city: {0}", change.Document.Id); } } });
Ruby
Trạng thái ban đầu có thể đến từ máy chủ trực tiếp hoặc từ bộ nhớ cache cục bộ. Nếu có trạng thái sẵn có trong bộ đệm cục bộ, ảnh chụp nhanh truy vấn sẽ được điền vào ban đầu với dữ liệu được lưu trong bộ đệm, sau đó được cập nhật với dữ liệu của máy chủ khi máy khách bắt kịp trạng thái của máy chủ.
Tách người nghe
Khi bạn không còn quan tâm đến việc nghe dữ liệu của mình, bạn phải tách bộ lắng nghe của mình ra để các lệnh gọi lại sự kiện của bạn ngừng được gọi. Điều này cho phép máy khách ngừng sử dụng băng thông để nhận các bản cập nhật. Ví dụ:
Web version 9
import { collection, onSnapshot } from "firebase/firestore"; const unsubscribe = onSnapshot(collection(db, "cities"), () => { // Respond to data // ... }); // Later ... // Stop listening to changes unsubscribe();
Web version 8
var unsubscribe = db.collection("cities") .onSnapshot(() => { // Respond to data // ... }); // Later ... // Stop listening to changes unsubscribe();
Nhanh
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];
Java
Query query = db.collection("cities"); ListenerRegistration registration = query.addSnapshotListener( new EventListener<QuerySnapshot>() { // ... }); // ... // Stop listening to changes registration.remove();
Kotlin+KTX
val query = db.collection("cities") val registration = query.addSnapshotListener { snapshots, e -> // ... } // ... // 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
Đi
PHP
// Not supported in the PHP client library
Đoàn kết
listener.Stop();
C#
await listener.StopAsync();
Ruby
Xử lý lỗi nghe
Đôi khi, quá trình lắng nghe có thể không thành công - ví dụ: do quyền bảo mật hoặc nếu bạn cố gắng lắng nghe một truy vấn không hợp lệ. (Tìm hiểu thêm về các truy vấn hợp lệ và không hợp lệ .) Để xử lý những lỗi này, bạn có thể cung cấp một lệnh gọi lại lỗi khi bạn đính kèm trình nghe ảnh chụp nhanh của mình. Sau một lỗi, người nghe sẽ không nhận được bất kỳ sự kiện nào nữa và không cần phải tách người nghe của bạn ra.
Web version 9
import { collection, onSnapshot } from "firebase/firestore"; const unsubscribe = onSnapshot( collection(db, "cities"), (snapshot) => { // ... }, (error) => { // ... });
Web version 8
db.collection("cities") .onSnapshot((snapshot) => { // ... }, (error) => { // ... });
Nhanh
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); } }];
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()); } } } });
Kotlin+KTX
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}") } } }
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
Đi
PHP
// Not supported in the PHP client library
Đoàn kết
// Not supported in the Unity SDK.
C#
// Snippet coming soon
Ruby
Cái gì tiếp theo
- Kết hợp người nghe với các truy vấn đơn giản và phức hợp .
- Đặt hàng và giới hạn các tài liệu được truy xuất .
- Hiểu thanh toán cho người nghe .