Bạn có thể nghe một tài liệu bằng phương thức onSnapshot()
. Lệnh gọi ban đầu bằng cách sử dụng lệnh gọi lại mà bạn cung cấp sẽ tạo ngay một bản tổng quan nhanh về tài liệu 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 lệnh gọi khác sẽ cập nhật ảnh chụp nhanh tài liệu.
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"), );
Thường thì bạn muốn giao diện người dùng phản ứng với những thay đổi về nội dung của một tài liệu hoặc bộ sưu tập Firestore. Bạn có thể làm việc này bằng tiện ích StreamBuilder
tiêu thụ 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
Tìm
PHP
// Not supported in the PHP client library
Unity
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
Sự kiện cho các thay đổi cục bộ
Các thao tác ghi cục bộ trong ứng dụng của bạn sẽ gọi ngay lập tức các trình nghe ảnh chụp nhanh. Điều này là do một tính năng quan trọng có tên là "bù độ trễ". Khi bạn thực hiện thao tác ghi, trình nghe của bạn sẽ được thông báo bằng dữ liệu mới trước khi dữ liệu được gửi đến phần 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 phần phụ trợ hay chưa. Bạn có thể dùng thuộc tính này để xác định nguồn của các sự kiện mà trình nghe ảnh chụp nhanh nhận được:
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
Tìm
// Not yet supported in the Go client library
PHP
// Not supported in the PHP client library
Unity
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
Sự kiện cho các thay đổi về siêu dữ liệu
Khi theo dõi các thay đổi đối với một tài liệu, tập hợp hoặc truy vấn, bạn có thể truyền các lựa chọn để kiểm soát mức độ chi tiết của các sự kiện mà trình nghe sẽ nhận được.
Theo mặc định, các trình nghe sẽ không nhận được thông báo về những thay đổi chỉ ảnh hưởng đến siêu dữ liệu. Hãy xem xét điều gì sẽ xảy ra khi ứng dụng của bạn ghi một tài liệu mới:
- Một sự kiện thay đổi sẽ được kích hoạt ngay lập tức bằng dữ liệu mới. Tài liệu này chưa được ghi vào phần phụ trợ nên cờ "pending writes" (đang chờ ghi) là
true
. - Tài liệu được ghi vào phần phụ trợ.
- Phần phụ trợ sẽ thông báo cho ứng dụng khách về thao tác ghi thành công. Dữ liệu tài liệu không thay đổi, nhưng siêu dữ liệu có thay đổi vì cờ "pending writes" (thao tá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 siêu dữ liệu của tài liệu hoặc truy vấn thay đổi, hãy truyền một đối tượng lựa chọn nghe khi đính kèm trình nghe.
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 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
Tìm
// Not yet supported in the Go client library
PHP
// Not supported in the PHP client library
Unity
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
Chỉ định cấu hình trình nghe cho các thay đổi cục bộ
Trình nghe ảnh chụp nhanh Cloud Firestore lấy ảnh chụp nhanh ban đầu từ bộ nhớ đệm cục bộ và đồng thời tìm nạp dữ liệu tương ứng từ máy chủ.
Trong một số trường hợp, bạn có thể không muốn các lần tìm nạp tiếp theo từ máy chủ. SDK ứng dụng cho phép bạn định cấu hình trình nghe chỉ kích hoạt liên quan đến dữ liệu trong bộ nhớ đệm cục bộ. Điều này giúp bạn tránh các lệnh gọi máy chủ không cần thiết và chi phí của chúng, đồng thời tận dụng bộ nhớ đệm phía máy khách, phản ánh dữ liệu và các đột biến cục bộ.
Ở đây, các lựa chọn về ảnh chụp nhanh được đặt trong mã ứng dụng để chỉ cho phép theo dõi các thay đổi cục bộ.
Web
const unsubscribe = onSnapshot( doc(db, "cities", "SF"), { includeMetadataChanges: true, source:'cache' }, (documentSnapshot) => {//…} );
Web
// Not yet supported in the Web namespaced API
Swift
// 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 library
Java
# Not yet supported in the Java client library
Python
// Not yet supported in Python client library
C++
// Not yet supported in the C++ client library
Node.js
// Not yet supported in the Node.js client library
Tìm
// Not yet supported in the Go client library
PHP
// Not yet supported in the PHP client library
Unity
// 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
Nghe nhiều tài liệu trong một bộ sưu tập
Tương tự như với tài liệu, bạn có thể dùng onSnapshot()
thay vì get()
để nghe kết quả của một truy vấn. Thao tác này sẽ tạo một ảnh chụp nhanh truy vấn. Ví dụ: để nghe các tài liệu có trạng thái 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
Tìm
PHP
// Not supported in the PHP client library
Unity
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
Trình xử lý ảnh chụp nhanh sẽ nhận được một ảnh chụp nhanh truy vấn mới mỗi khi kết quả truy vấn thay đổi (tức là khi một tài liệu được thêm, xoá hoặc sửa đổi).
Xem các thay đổi giữa các ảnh chụp nhanh
Thường thì bạn nên xem những 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ớ đệm khi các tài liệu riêng lẻ được thêm, xoá và sửa đổi.
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
Tìm
PHP
// Not supported in the PHP client library
Unity
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
Trạng thái ban đầu có thể đến trực tiếp từ máy chủ hoặc từ bộ nhớ đệm cục bộ. Nếu có trạng thái trong bộ nhớ đệm cục bộ, thì ảnh chụp nhanh truy vấn ban đầu sẽ được điền sẵn bằng dữ liệu trong bộ nhớ đệm, sau đó được cập nhật bằng 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 trình nghe
Khi không còn muốn theo dõi dữ liệu nữa, bạn phải tách trình nghe để các lệnh gọi lại sự kiệ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 thông tin cập nhật. Ví dụ:
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
Tìm
PHP
// Not supported in the PHP client library
Unity
listener.Stop();
C#
Ruby
Xử lý lỗi nghe
Đôi khi, lệnh nghe có thể không hoạt động, chẳng hạn như do quyền bảo mật hoặc nếu bạn cố gắng nghe một truy vấn không hợp lệ. (Tìm hiểu thêm về cụm từ tìm kiếm 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 đính kèm trình nghe ảnh chụp nhanh. Sau khi xảy ra lỗi, trình nghe sẽ không nhận được thêm sự kiện nào nữa và bạn không cần tách trình nghe.
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
Tìm
PHP
// Not supported in the PHP client library
Unity
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
Bước tiếp theo
- Kết hợp các trình nghe với truy vấn đơn giản và truy vấn phức tạp.
- Sắp xếp và giới hạn số lượng tài liệu được truy xuất.
- Tìm hiểu về việc tính phí đối với người nghe.