Join us for Firebase Summit on November 10, 2021. Tune in to learn how Firebase can help you accelerate app development, release with confidence, and scale with ease. Register

קבל עדכונים בזמן אמת באמצעות Cloud Firestore

ניתן להאזין מסמך עם onSnapshot() שיטה. שיחה ראשונית באמצעות החיוג החוזר שאתה מספק יוצרת תמונת מצב של המסמך באופן מיידי עם התוכן הנוכחי של המסמך היחיד. לאחר מכן, בכל פעם שהתוכן משתנה, שיחה נוספת מעדכנת את תמונת המסמך.

גרסת אינטרנט 9

import { doc, onSnapshot } from "firebase/firestore";

const unsub = onSnapshot(doc(db, "cities", "SF"), (doc) => {
    console.log("Current data: ", doc.data());
});

גרסת אינטרנט 8

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)")
    }
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);
    }];

ג'אווה

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");
        }
    }
});

קוטלין+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")
    }
}
ג'אווה
DocumentReference docRef = db.collection("cities").document("SF");
docRef.addSnapshotListener(new EventListener<DocumentSnapshot>() {
  @Override
  public void onEvent(@Nullable DocumentSnapshot snapshot,
                      @Nullable FirestoreException e) {
    if (e != null) {
      System.err.println("Listen failed: " + e);
      return;
    }

    if (snapshot != null && snapshot.exists()) {
      System.out.println("Current data: " + snapshot.getData());
    } else {
      System.out.print("Current data: null");
    }
  }
});
פִּיתוֹן

# Create an Event for notifying main thread.
callback_done = threading.Event()

# Create a callback on_snapshot function to capture changes
def on_snapshot(doc_snapshot, changes, read_time):
    for doc in doc_snapshot:
        print(f'Received document snapshot: {doc.id}')
    callback_done.set()

doc_ref = db.collection(u'cities').document(u'SF')

# Watch the document
doc_watch = doc_ref.on_snapshot(on_snapshot)
C ++
DocumentReference doc_ref = db->Collection("cities").Document("SF");
doc_ref.AddSnapshotListener(
    [](const DocumentSnapshot& snapshot, Error error) {
      if (error == Error::kErrorOk) {
        if (snapshot.exists()) {
          std::cout << "Current data: " << snapshot << '\n';
        } else {
          std::cout << "Current data: null\n";
        }
      } else {
        std::cout << "Listen failed: " << error << '\n';
      }
    });
Node.js
const doc = db.collection('cities').doc('SF');

const observer = doc.onSnapshot(docSnapshot => {
  console.log(`Received doc snapshot: ${docSnapshot}`);
  // ...
}, err => {
  console.log(`Encountered error: ${err}`);
});
ללכת
import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/firestore"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

// listenDocument listens to a single document.
func listenDocument(ctx context.Context, w io.Writer, projectID, collection string) error {
	// projectID := "project-id"
	// Сontext with timeout stops listening to changes.
	ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
	defer cancel()

	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("firestore.NewClient: %v", err)
	}
	defer client.Close()

	it := client.Collection(collection).Doc("SF").Snapshots(ctx)
	for {
		snap, err := it.Next()
		// DeadlineExceeded will be returned when ctx is cancelled.
		if status.Code(err) == codes.DeadlineExceeded {
			return nil
		}
		if err != nil {
			return fmt.Errorf("Snapshots.Next: %v", err)
		}
		if !snap.Exists() {
			fmt.Fprintf(w, "Document no longer exists\n")
			return nil
		}
		fmt.Fprintf(w, "Received document snapshot: %v\n", snap.Data())
	}
}
PHP
// 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));
    }
});
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);
        }
    }
});
אוֹדֶם
doc_ref = firestore.col(collection_path).doc document_path
snapshots = []

# Watch the document.
listener = doc_ref.listen do |snapshot|
  puts "Received document snapshot: #{snapshot.document_id}"
  snapshots << snapshot
end

אירועים לשינויים מקומיים

כתובות מקומיות באפליקציה שלך יפעילו מאזיני תצלום מיידית. הסיבה לכך היא תכונה חשובה הנקראת "פיצוי חביון". בעת ביצוע כתיבה, המאזינים שלך תישלח הודעה עם הנתונים החדשים לפני שהנתונים נשלחים backend.

יש מסמכים שלף שטר metadata.hasPendingWrites רכוש ולציין אם המסמך יש שינויים מקומיים שלא היה בכתב backend עדיין. תוכל להשתמש בנכס זה כדי לקבוע את מקור האירועים שקיבל מאזין התצלומים שלך:

גרסת אינטרנט 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());
});

גרסת אינטרנט 8

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() ?? [:])")
    }
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);
    }];

ג'אווה

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");
        }
    }
});

קוטלין+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")
    }
}
ג'אווה
# Not yet supported in the Java client library
פִּיתוֹן
// Not yet supported in Python client library
C ++
DocumentReference doc_ref = db->Collection("cities").Document("SF");
doc_ref.AddSnapshotListener([](const DocumentSnapshot& snapshot,
                               Error error) {
  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()
                << '\n';
    } else {
      std::cout << source << " data: null\n";
    }
  } else {
    std::cout << "Listen failed: " << error << '\n';
  }
});
Node.js
// Not yet supported in the Node.js client library
ללכת
// Not yet supported in the Go client library
PHP
// Not supported in the PHP client library
אַחְדוּת
// Not yet supported in the Unity SDK
C#
// Not yet supported in the C# client library
אוֹדֶם
// Not yet supported in the Ruby client library

אירועים לשינויים במטא נתונים

בעת האזנה לשינויים במסמך, באוסף או בשאילתה, תוכל להעביר אפשרויות לשלוט במפורטות האירועים שהמאזין שלך יקבל.

כברירת מחדל, המאזינים אינם מקבלים הודעה על שינויים המשפיעים רק על מטא נתונים. שקול מה קורה כאשר האפליקציה שלך כותבת מסמך חדש:

  1. אירוע שינוי מופעל מיד עם הנתונים החדשים. המסמך טרם בכתב backend כך הדגל "כותב בהמתנה" הוא true .
  2. המסמך נכתב אל הצד האחורי.
  3. ה- backend מודיע ללקוח על הכתיבה המוצלחת. אין שינוי נתוני המסמך, אך יש שינוי metadata בגלל דגל "כותב בהמתנה" הוא עכשיו false .

אם ברצונך לקבל אירועי תמונת מצב כאשר מטא הנתונים של המסמך או השאילתה משתנים, העבר אובייקט אפשרויות האזנה בעת צירוף המאזין שלך:

גרסת אינטרנט 9

import { doc, onSnapshot } from "firebase/firestore";

const unsub = onSnapshot(
  doc(db, "cities", "SF"), 
  { includeMetadataChanges: true }, 
  (doc) => {
    // ...
  });

גרסת אינטרנט 8

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
        // ...
    }
Objective-C
// Listen for metadata changes.
[[[self.db collectionWithPath:@"cities"] documentWithPath:@"SF"]
    addSnapshotListenerWithIncludeMetadataChanges:YES
                                         listener:^(FIRDocumentSnapshot *snapshot, NSError *error) {
   // ...
}];

ג'אווה

// 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) {
        // ...
    }
});

קוטלין+KTX

// Listen for metadata changes to the document.
val docRef = db.collection("cities").document("SF")
docRef.addSnapshotListener(MetadataChanges.INCLUDE) { snapshot, e ->
    // ...
}
ג'אווה
// Not yet supported in the Java client library
פִּיתוֹן
// 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) { /* ... */ });
Node.js
// Not yet supported the Node.js client library
ללכת
// Not yet supported in the Go client library
PHP
// Not supported in the PHP client library
אַחְדוּת
// Not yet supported in the Unity SDK
C#
// Not yet supported in the C# client library
אוֹדֶם
// Not yet supported in the Ruby client library

האזן למספר מסמכים באוסף

כמו עם מסמכים, אתה יכול להשתמש onSnapshot() במקום get() כדי להאזין התוצאות של שאילתה. פעולה זו יוצרת תמונת מצב של שאילתה. לדוגמה, כדי להאזין המסמכים עם המדינה CA :

גרסת אינטרנט 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(", "));
});

גרסת אינטרנט 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(", "));
    });
מָהִיר
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);
    }];

ג'אווה

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);
            }
        });

קוטלין+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")
        }
ג'אווה
db.collection("cities")
    .whereEqualTo("state", "CA")
    .addSnapshotListener(new EventListener<QuerySnapshot>() {
      @Override
      public void onEvent(@Nullable QuerySnapshot snapshots,
                          @Nullable FirestoreException e) {
        if (e != null) {
          System.err.println("Listen failed:" + e);
          return;
        }

        List<String> cities = new ArrayList<>();
        for (DocumentSnapshot doc : snapshots) {
          if (doc.get("name") != null) {
            cities.add(doc.getString("name"));
          }
        }
        System.out.println("Current cites in CA: " + cities);
      }
    });
פִּיתוֹן

# Create an Event for notifying main thread.
callback_done = threading.Event()

# Create a callback on_snapshot function to capture changes
def on_snapshot(col_snapshot, changes, read_time):
    print(u'Callback received query snapshot.')
    print(u'Current cities in California:')
    for doc in col_snapshot:
        print(f'{doc.id}')
    callback_done.set()

col_query = db.collection(u'cities').where(u'state', u'==', u'CA')

# Watch the collection query
query_watch = col_query.on_snapshot(on_snapshot)
C ++
db->Collection("cities")
    .WhereEqualTo("state", FieldValue::String("CA"))
    .AddSnapshotListener([](const QuerySnapshot& snapshot, Error error) {
      if (error == Error::kErrorOk) {
        std::vector<std::string> cities;
        std::cout << "Current cities in CA: " << error << '\n';
        for (const DocumentSnapshot& doc : snapshot.documents()) {
          cities.push_back(doc.Get("name").string_value());
          std::cout << "" << cities.back() << '\n';
        }
      } else {
        std::cout << "Listen failed: " << error << '\n';
      }
    });
Node.js
const query = db.collection('cities').where('state', '==', 'CA');

const observer = query.onSnapshot(querySnapshot => {
  console.log(`Received query snapshot of size ${querySnapshot.size}`);
  // ...
}, err => {
  console.log(`Encountered error: ${err}`);
});
ללכת
import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/firestore"
	"google.golang.org/api/iterator"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

// listenMultiple listens to a query, returning the names of all cities
// for a state.
func listenMultiple(ctx context.Context, w io.Writer, projectID, collection string) error {
	// projectID := "project-id"
	ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
	defer cancel()

	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("firestore.NewClient: %v", err)
	}
	defer client.Close()

	it := client.Collection(collection).Where("state", "==", "CA").Snapshots(ctx)
	for {
		snap, err := it.Next()
		// DeadlineExceeded will be returned when ctx is cancelled.
		if status.Code(err) == codes.DeadlineExceeded {
			return nil
		}
		if err != nil {
			return fmt.Errorf("Snapshots.Next: %v", err)
		}
		if snap != nil {
			for {
				doc, err := snap.Documents.Next()
				if err == iterator.Done {
					break
				}
				if err != nil {
					return fmt.Errorf("Documents.Next: %v", err)
				}
				fmt.Fprintf(w, "Current cities in California: %v\n", doc.Ref.ID)
			}
		}
	}
}
PHP
// 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);
  }
});
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);
    }
});
אוֹדֶם
query = firestore.col(collection_path).where :state, :==, "CA"
docs = []

# Watch the collection query.
listener = query.listen do |snapshot|
  puts "Callback received query snapshot."
  puts "Current cities in California:"
  snapshot.docs.each do |doc|
    puts doc.document_id
    docs << doc
  end
end

מטפל התצלומים יקבל תמונת מצב חדשה של שאילתה בכל פעם שתוצאות השאילתה משתנות (כלומר, כאשר מסמך נוסף, מוסר או משתנה).

הצג שינויים בין תמונות

לעתים קרובות מועיל לראות את השינויים בפועל בתוצאות השאילתה בין תצלומי השאילתה, במקום פשוט להשתמש בכל תמונת המצב של השאילתה. לדוגמה, ייתכן שתרצה לשמור על מטמון כאשר נוספים, מסירים ומשנים מסמכים בודדים.

גרסת אינטרנט 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());
    }
  });
});

גרסת אינטרנט 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());
            }
        });
    });
מָהִיר
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);
        }
      }
    }];

ג'אווה

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;
                    }
                }

            }
        });

קוטלין+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}")
                }
            }
        }
ג'אווה
db.collection("cities")
    .whereEqualTo("state", "CA")
    .addSnapshotListener(new EventListener<QuerySnapshot>() {
      @Override
      public void onEvent(@Nullable QuerySnapshot snapshots,
                          @Nullable FirestoreException e) {
        if (e != null) {
          System.err.println("Listen failed: " + e);
          return;
        }

        for (DocumentChange dc : snapshots.getDocumentChanges()) {
          switch (dc.getType()) {
            case ADDED:
              System.out.println("New city: " + dc.getDocument().getData());
              break;
            case MODIFIED:
              System.out.println("Modified city: " + dc.getDocument().getData());
              break;
            case REMOVED:
              System.out.println("Removed city: " + dc.getDocument().getData());
              break;
            default:
              break;
          }
        }
      }
    });
C ++
db->Collection("cities")
    .WhereEqualTo("state", FieldValue::String("CA"))
    .AddSnapshotListener([](const QuerySnapshot& snapshot, Error error) {
      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() << '\n';
              break;
            case DocumentChange::Type::kModified:
              std::cout << "Modified city: "
                        << dc.document().Get("name").string_value() << '\n';
              break;
            case DocumentChange::Type::kRemoved:
              std::cout << "Removed city: "
                        << dc.document().Get("name").string_value() << '\n';
              break;
          }
        }
      } else {
        std::cout << "Listen failed: " << error << '\n';
      }
    });
פִּיתוֹן

# Create an Event for notifying main thread.
delete_done = threading.Event()

# Create a callback on_snapshot function to capture changes
def on_snapshot(col_snapshot, changes, read_time):
    print(u'Callback received query snapshot.')
    print(u'Current cities in California: ')
    for change in changes:
        if change.type.name == 'ADDED':
            print(f'New city: {change.document.id}')
        elif change.type.name == 'MODIFIED':
            print(f'Modified city: {change.document.id}')
        elif change.type.name == 'REMOVED':
            print(f'Removed city: {change.document.id}')
            delete_done.set()

col_query = db.collection(u'cities').where(u'state', u'==', u'CA')

# Watch the collection query
query_watch = col_query.on_snapshot(on_snapshot)
Node.js
const observer = db.collection('cities').where('state', '==', 'CA')
  .onSnapshot(querySnapshot => {
    querySnapshot.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());
      }
    });
  });
ללכת
import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/firestore"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

// listenChanges listens to a query, returning the list of document changes.
func listenChanges(ctx context.Context, w io.Writer, projectID, collection string) error {
	// projectID := "project-id"
	ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
	defer cancel()

	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("firestore.NewClient: %v", err)
	}
	defer client.Close()

	it := client.Collection(collection).Where("state", "==", "CA").Snapshots(ctx)
	for {
		snap, err := it.Next()
		// DeadlineExceeded will be returned when ctx is cancelled.
		if status.Code(err) == codes.DeadlineExceeded {
			return nil
		}
		if err != nil {
			return fmt.Errorf("Snapshots.Next: %v", err)
		}
		if snap != nil {
			for _, change := range snap.Changes {
				switch change.Kind {
				case firestore.DocumentAdded:
					fmt.Fprintf(w, "New city: %v\n", change.Doc.Data())
				case firestore.DocumentModified:
					fmt.Fprintf(w, "Modified city: %v\n", change.Doc.Data())
				case firestore.DocumentRemoved:
					fmt.Fprintf(w, "Removed city: %v\n", change.Doc.Data())
				}
			}
		}
	}
}
PHP
// 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));
                }
            }
        });
    }
}
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);
        }
    }
});
אוֹדֶם
query = firestore.col(collection_path).where :state, :==, "CA"
added = []
modified = []
removed = []

# Watch the collection query.
listener = query.listen do |snapshot|
  puts "Callback received query snapshot."
  puts "Current cities in California:"
  snapshot.changes.each do |change|
    if change.added?
      puts "New city: #{change.doc.document_id}"
      added << snapshot
    elsif change.modified?
      puts "Modified city: #{change.doc.document_id}"
      modified << snapshot
    elsif change.removed?
      puts "Removed city: #{change.doc.document_id}"
      removed << snapshot
    end
  end
end

המצב ההתחלתי יכול להגיע מהשרת ישירות, או מהמטמון המקומי. אם יש מצב זמין במטמון מקומי, תמונת מצב השאילתה תתאכלס בתחילה בנתוני המטמון, ולאחר מכן תתעדכן בנתוני השרת כאשר הלקוח ישיג את מצב השרת.

נתק מאזין

כאשר אינך מעוניין עוד להאזין לנתונים שלך, עליך לנתק את המאזין שלך כך שהשיחות החזרה לאירוע יפסיקו להתקשר אליך. זה מאפשר ללקוח להפסיק להשתמש ברוחב הפס כדי לקבל עדכונים. לדוגמה:

גרסת אינטרנט 9

import { collection, onSnapshot } from "firebase/firestore";

const unsubscribe = onSnapshot(collection(db, "cities"), () => {
  // Respond to data
  // ...
});

// Later ...

// Stop listening to changes
unsubscribe();

גרסת אינטרנט 8

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()
Objective-C
id<FIRListenerRegistration> listener = [[self.db collectionWithPath:@"cities"]
    addSnapshotListener:^(FIRQuerySnapshot *snapshot, NSError *error) {
      // ...
}];

// ...

// Stop listening to changes
[listener remove];

ג'אווה

Query query = db.collection("cities");
ListenerRegistration registration = query.addSnapshotListener(
        new EventListener<QuerySnapshot>() {
            // ...
        });

// ...

// Stop listening to changes
registration.remove();

קוטלין+KTX

val query = db.collection("cities")
val registration = query.addSnapshotListener { snapshots, e ->
    // ...
}

// ...

// Stop listening to changes
registration.remove()
ג'אווה
Query query = db.collection("cities");
ListenerRegistration registration = query.addSnapshotListener(
    new EventListener<QuerySnapshot>() {
      // ...
    });

// ...

// Stop listening to changes
registration.remove();
פִּיתוֹן
# Terminate watch on a document
doc_watch.unsubscribe()
C ++
// Add a listener
Query query = db->Collection("cities");
ListenerRegistration registration = query.AddSnapshotListener(
    [](const QuerySnapshot& snapshot, Error error) { /* ... */ });
// Stop listening to changes
registration.Remove();
Node.js
const unsub = db.collection('cities').onSnapshot(() => {
});

// ...

// Stop listening for changes
unsub();
ללכת
// Сontext with timeout stops listening to changes.
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()
PHP
// Not supported in the PHP client library
אַחְדוּת
listener.Stop();
C#
await listener.StopAsync();
אוֹדֶם
listener.stop

לטפל בשגיאות האזנה

מדי פעם הקשבה עלולה להיכשל - למשל בשל הרשאות אבטחה, או אם ניסית להאזין לשאילתה לא חוקית. (למידע נוסף על שאילתה חוקיות ולא-חוקיות .) כדי להתמודד עם כשלים אלה, אתה יכול לספק התקשרות שגיאה כאשר אתה מצרף מאזין תמונת המצב שלך. לאחר שגיאה, המאזין לא יקבל אירועים נוספים, ואין צורך לנתק את המאזין שלך.

גרסת אינטרנט 9

import { collection, onSnapshot } from "firebase/firestore";

const unsubscribe = onSnapshot(
  collection(db, "cities"), 
  (snapshot) => {
    // ...
  },
  (error) => {
    // ...
  });

גרסת אינטרנט 8

db.collection("cities")
    .onSnapshot((snapshot) => {
        // ...
    }, (error) => {
        // ...
    });
מָהִיר
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);
      }
    }];

ג'אווה

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());
                    }
                }

            }
        });

קוטלין+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}")
                }
            }
        }
ג'אווה
db.collection("cities")
    .addSnapshotListener(new EventListener<QuerySnapshot>() {
      @Override
      public void onEvent(@Nullable QuerySnapshot snapshots,
                          @Nullable FirestoreException e) {
        if (e != null) {
          System.err.println("Listen failed: " + e);
          return;
        }

        for (DocumentChange dc : snapshots.getDocumentChanges()) {
          if (dc.getType() == Type.ADDED) {
            System.out.println("New city: " + dc.getDocument().getData());
          }
        }
      }
    });
פִּיתוֹן
// Snippet coming soon
C ++
// This is not yet supported.
Node.js
db.collection('cities')
  .onSnapshot((snapshot) => {
    //...
  }, (error) => {
    //...
  });
ללכת
import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/firestore"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

// listenErrors demonstrates how to handle listening errors.
func listenErrors(ctx context.Context, w io.Writer, projectID, collection string) error {
	// projectID := "project-id"
	ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
	defer cancel()

	client, err := firestore.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("firestore.NewClient: %v", err)
	}
	defer client.Close()

	it := client.Collection(collection).Snapshots(ctx)
	for {
		snap, err := it.Next()
		// DeadlineExceeded will be returned when ctx is cancelled.
		if status.Code(err) == codes.DeadlineExceeded {
			return nil
		}
		if err != nil {
			return fmt.Errorf("Snapshots.Next: %v", err)
		}
		if snap != nil {
			for _, change := range snap.Changes {
				if change.Kind == firestore.DocumentAdded {
					fmt.Fprintf(w, "New city: %v\n", change.Doc.Data())
				}
			}
		}
	}
}
PHP
// Not supported in the PHP client library
אַחְדוּת
// Not supported in the Unity SDK.
C#
// Snippet coming soon
אוֹדֶם
listener = firestore.col(collection_path).listen do |snapshot|
  snapshot.changes.each do |change|
    puts "New city: #{change.doc.document_id}" if change.added?
  end
end

# Register to be notified when unhandled errors occur.
listener.on_error do |error|
  puts "Listen failed: #{error.message}"
end

מה הלאה