คุณสามารถฟังเอกสารด้วยเมธอด 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+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") } }
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"), );
บ่อยครั้งที่คุณต้องการให้ UI ตอบสนองต่อการเปลี่ยนแปลงในเนื้อหาของเอกสารหรือคอลเล็กชัน 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
Go
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
เหตุการณ์สําหรับการเปลี่ยนแปลงในเครื่อง
การเขียนในเครื่องในแอปจะเรียกใช้เครื่องมือรับฟังภาพรวมทันที สาเหตุเป็นเพราะฟีเจอร์สําคัญที่เรียกว่า "การชดเชยเวลาในการตอบสนอง" เมื่อคุณทำการเขียน ผู้ฟังจะได้รับการแจ้งเตือนข้อมูลใหม่ก่อนที่ระบบจะส่งข้อมูลไปยังแบ็กเอนด์
เอกสารที่ดึงข้อมูลจะมีพร็อพเพอร์ตี้ metadata.hasPendingWrites
ที่ระบุว่าเอกสารมีการเปลี่ยนแปลงในเครื่องที่ยังไม่ได้เขียนลงในแบ็กเอนด์หรือไม่ คุณสามารถใช้พร็อพเพอร์ตี้นี้เพื่อระบุแหล่งที่มาของเหตุการณ์ที่ 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()); });
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+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") } }
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
Go
// 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
เหตุการณ์สำหรับการเปลี่ยนแปลงข้อมูลเมตา
เมื่อรอฟังการเปลี่ยนแปลงในเอกสาร คอลเล็กชัน หรือคําค้นหา คุณสามารถส่งตัวเลือกเพื่อควบคุมความละเอียดของเหตุการณ์ที่ Listener จะได้รับ
โดยค่าเริ่มต้น ผู้ฟังจะไม่ได้รับแจ้งเกี่ยวกับการเปลี่ยนแปลงที่ส่งผลต่อข้อมูลเมตาเท่านั้น พิจารณาสิ่งที่จะเกิดขึ้นเมื่อแอปเขียนเอกสารใหม่
- ระบบจะเรียกเหตุการณ์การเปลี่ยนแปลงด้วยข้อมูลใหม่ทันที ระบบยังไม่ได้เขียนเอกสารไปยังแบ็กเอนด์ ดังนั้นธง "การเขียนที่รอดำเนินการ" จึงเป็น
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+KTX
// 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
Go
// 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
กำหนดค่า Listeners สำหรับการเปลี่ยนแปลงในเครื่องเท่านั้น
Cloud Firestore เครื่องมือรับฟังสแนปชอตจะจับภาพเริ่มต้นจากแคชในเครื่อง และดึงข้อมูลที่เกี่ยวข้องจากเซิร์ฟเวอร์พร้อมกัน
ในบางกรณี คุณอาจไม่ต้องการการดึงข้อมูลติดตามผลจากเซิร์ฟเวอร์ SDK ของไคลเอ็นต์ช่วยให้คุณกําหนดค่า Listeners ให้ทํางานเฉพาะกับข้อมูลในแคชในเครื่องได้ วิธีนี้ช่วยให้คุณหลีกเลี่ยงการเรียกใช้เซิร์ฟเวอร์ที่ไม่จำเป็นและค่าใช้จ่ายที่เกี่ยวข้อง รวมถึงใช้ประโยชน์จากแคชฝั่งไคลเอ็นต์ซึ่งแสดงข้อมูลในเครื่องและการเปลี่ยนแปลง
ที่นี่จะมีการตั้งค่าตัวเลือกสแนปชอตในโค้ดไคลเอ็นต์เพื่ออนุญาตให้ฟังการเปลี่ยนแปลงในเครื่องเท่านั้น
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+KTX
// 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
Go
// 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
ฟังเอกสารหลายรายการในคอลเล็กชัน
คุณสามารถใช้ 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+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") }
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
Go
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
แฮนเดิลสแนปชอตจะได้รับสแนปชอตการค้นหาใหม่ทุกครั้งที่ผลการค้นหามีการเปลี่ยนแปลง (นั่นคือเมื่อมีการเพิ่ม นําออก หรือแก้ไขเอกสาร)
ดูการเปลี่ยนแปลงระหว่างภาพรวม
บางครั้งการดูการเปลี่ยนแปลงจริงของผลการค้นหาระหว่างสแนปชอตการค้นหาแทนการใช้สแนปชอตการค้นหาทั้งหมดจะมีประโยชน์มากกว่า เช่น คุณอาจต้องเก็บรักษาแคชไว้เมื่อมีการเพิ่ม นําออก และแก้ไขเอกสารแต่ละรายการ
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+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}") } } }
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
Go
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
สถานะเริ่มต้นอาจมาจากเซิร์ฟเวอร์โดยตรงหรือมาจากแคชในเครื่องก็ได้ หากมีสถานะในแคชในเครื่อง ระบบจะป้อนข้อมูลแคชลงในสแนปชอตการค้นหาในตอนแรก จากนั้นจะอัปเดตด้วยข้อมูลของเซิร์ฟเวอร์เมื่อไคลเอ็นต์มีสถานะเท่ากับเซิร์ฟเวอร์
แยก Listener
เมื่อไม่สนใจที่จะฟังข้อมูลอีกต่อไป คุณต้องยกเลิกการเชื่อมโยงโปรแกรมฟังเพื่อให้ระบบหยุดเรียกใช้การเรียกกลับเหตุการณ์ ซึ่งจะช่วยให้ไคลเอ็นต์หยุดใช้แบนด์วิดท์เพื่อรับการอัปเดต เช่น
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+KTX
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
Go
PHP
// Not supported in the PHP client library
Unity
listener.Stop();
C#
Ruby
จัดการข้อผิดพลาดในการฟัง
บางครั้งการฟังอาจไม่สำเร็จ เช่น เนื่องจากสิทธิ์ด้านความปลอดภัย หรือหากคุณพยายามฟังการค้นหาที่ไม่ถูกต้อง (ดูข้อมูลเพิ่มเติมเกี่ยวกับคำค้นหาที่ถูกต้องและไม่ถูกต้อง) หากต้องการจัดการกับข้อผิดพลาดเหล่านี้ คุณสามารถระบุการเรียกกลับข้อผิดพลาดเมื่อแนบโปรแกรมรับฟังภาพรวม หลังจากเกิดข้อผิดพลาด Listener จะไม่รับเหตุการณ์อีกต่อไป และคุณไม่จำเป็นต้องถอด Listener
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+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}") } } }
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
Go
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
ขั้นตอนถัดไป
- รวม Listener เข้ากับคําค้นหาแบบง่ายและแบบผสม
- จัดเรียงและจำกัดเอกสารที่ดึงข้อมูล
- ทำความเข้าใจการเรียกเก็บเงินจากผู้ฟัง