Skip to content
This repository has been archived by the owner on May 17, 2022. It is now read-only.

K.7 Query Get Realtime Updates

Hadi Tavakoli edited this page Dec 16, 2017 · 1 revision

Get Realtime Updates with Cloud Firestore

You can listen to a document with the addSnapshotListener method. An initial call using the callback you provide creates a document snapshot immediately with the current contents of the single document. Then, each time the contents change, another call updates the document snapshot.

var document:DocumentReference = Firestore.collection("cities").document("SF");
document.addSnapshotListener(onSnapshotListenerSuccess, onSnapshotListenerFailure);

function onSnapshotListenerSuccess(e:FirestoreEvents):void
{
	trace("onSnapshotListenerSuccess: "+JSON.stringify(e.documentSnapshot.data));
}

function onSnapshotListenerFailure(e:FirestoreEvents):void
{
	trace("onSnapshotListenerFailure: " + e.msg);
}

Events for local changes

In the previous example, the callback was called twice after setting San Francisco's population to 999999. This is because of an important feature called "latency compensation." When you perform a write, your listeners will be notified with the new data immediately, before the data is even sent to the backend database.

As shown above, your listener will then be notified again once the data is actually written to the backend. This could take any amount of time from a few milliseconds to a few hours, depending on the state of your network connection.

Retrieved documents have a metadata.hasPendingWrites property that indicates whether the document has local changes that haven't been written to the backend yet. You can use this property to repeat the previous example but show the difference between the two events:

var document:DocumentReference = Firestore.collection("cities").document("SF");
document.addSnapshotListener(onSnapshotListenerSuccess, onSnapshotListenerFailure);

function onSnapshotListenerSuccess(e:FirestoreEvents):void
{
	if(e.documentSnapshot)
	{
		trace("onSnapshotListenerSuccess: "+JSON.stringify(e.documentSnapshot.data));
		var source:String = (e.documentSnapshot.metadata.hasPendingWrites)? "local" : "server";
		trace("source of changes: " + source);
	}
	else
	{
		trace("document '" + document.documentId + "' is not available yet");
	}
}

function onSnapshotListenerFailure(e:FirestoreEvents):void
{
	trace("onSnapshotListenerFailure: " + e.msg);
}

Listen to multiple documents in a collection

As with documents, you can use addSnapshotListener instead of read() to listen to the results of a query. This creates a query snapshot. For example, to listen to the documents with state CA:

var query:Query = Firestore.collection("cities").whereEqualTo("state", "CA");
query.addSnapshotListener(onSnapshotListenerSuccess, onSnapshotListenerFailure);

function onSnapshotListenerSuccess(e:FirestoreEvents):void
{
	if(e.querySnapshot)
	{
		var cities:Array = [];
		for(var i:int=0; i < e.querySnapshot.documents.length; i++)
		{
			var currSnapshot:DocumentSnapshot = e.querySnapshot.documents[i];
			cities.push(currSnapshot.data.name);
		}
		
		trace("Current cites in CA: " + cities);
	}
	else
	{
		trace("querySnapshot is not available");
	}
}

function onSnapshotListenerFailure(e:FirestoreEvents):void
{
	trace("Listen failed: " + e.msg);
}

The snapshot handler will receive a new query snapshot every time the query results change (that is, when a document is added, removed, or modified).

View changes between snapshots

It is often useful to see the actual changes to query results between query snapshots, instead of simply using the entire query snapshot. For example, you may want to maintain a cache as individual documents are added, removed, and modified.

var query:Query = Firestore.collection("cities").whereEqualTo("state", "CA");
query.addSnapshotListener(onSnapshotListenerSuccess, onSnapshotListenerFailure);

function onSnapshotListenerSuccess(e:FirestoreEvents):void
{
	if(e.querySnapshot)
	{
		for(var i:int=0; i < e.querySnapshot.documentChanges.length; i++)
		{
			var currChange:DocumentChange = e.querySnapshot.documentChanges[i];
			switch(currChange.changeType)
			{
				case DocumentChange.ADDED:
					
					trace("New city: " + JSON.stringify(currChange.document.data));
					
					break;
				case DocumentChange.MODIFIED:
					
					trace("Modified city: " + JSON.stringify(currChange.document.data));
					
					break;
				case DocumentChange.REMOVED:
					
					trace("Removed city: " + JSON.stringify(currChange.document.data));
					
					break;
			}
		}
	}
	else
	{
		trace("querySnapshot is not available");
	}
}

function onSnapshotListenerFailure(e:FirestoreEvents):void
{
	trace("Listen failed: " + e.msg);
}

Important: The first query snapshot contains added events for all existing documents that match the query. This is because you're getting a set of changes that bring your query snapshot current with the initial state of the query. This allows you, for instance, to directly populate your UI from the changes you receive in the first query snapshot, without needing to add special logic for handling the initial state.

The initial state can come from the server directly, or from a local cache. If there is state available in a local cache, the query snapshot will be initially populated with the cached data, then updated with the server's data when the client has caught up with the server's state.

Detach a listener

When you are no longer interested in listening to your data, you must detach your listener so that your event callbacks stop getting called. This allows the client to stop using bandwidth to receive updates. You can use the removeSnapshotListener function to stop listening to updates.

Handle listen errors

A listen may occasionally fail — for example, due to security permissions, or if you tried to listen on an invalid query. (Learn more about valid and invalid queries.) To handle these failures, you can provide an error callback when you attach your snapshot listener. After an error, the listener will not receive any more events, and there is no need to detach your listener.

Introduction to Firebase ANEs collection for Adobe Air apps


Get Started with Firebase Core in AIR

  1. Prerequisites
  2. Add Firebase to your app
  3. Add the Firebase SDK
  4. Init Firebase Core
  5. Available ANEs
  6. Managing Firebase iid

Get Started with Analytics

  1. Add Analytics ANE
  2. Init Analytics ANE
  3. Log Events
  4. Set User Properties

Get Started with Crashlytics

  1. Add Crashlytics ANE
  2. Test Your Implementation
  3. Customize Crash Reports
  4. Upload .dSYM for iOS apps

Get Started with DynamicLinks

  1. Add DynamicLinks ANE
  2. Init DynamicLinks ANE
  3. Create DynamicLinks
  4. Receive DynamicLinks
  5. View Analytics

Get Started with Authentication

  1. Add Authentication
  2. Init Authentication
  3. Manage Users
  4. Phone Number
  5. Custom Auth
  6. Anonymous Auth
  7. State in Email Actions
  8. Email Link Authentication

Get Started with FCM + OneSignal

  1. Add FCM ANE
  2. Init FCM ANE
  3. Send Your 1st Message
  4. Send Msg to Topics
  5. Understanding FCM Messages
  6. init OneSignal

Get Started with Firestore

  1. Add Firestore
  2. Init Firestore
  3. Add Data
  4. Transactions & Batches
  5. Delete Data
  6. Manage the Console
  7. Get Data
  8. Get Realtime Updates
  9. Simple and Compound
  10. Order and Limit Data
  11. Paginate Data
  12. Manage Indexes
  13. Secure Data
  14. Offline Data
  15. Where to Go From Here

Get Started with Realtime Database

  1. Add Realtime Database
  2. Init Realtime Database
  3. Structure Your Database
  4. Save Data
  5. Retrieve Data
  6. Enable Offline Capabilities

Get Started with Remote Config

  1. Parameters and Conditions
  2. Add Remote Config
  3. Init Remote Config

Get Started with Performance

  1. Add Performance ANE
  2. Init & Start Monitoring

Get Started with Storage

  1. Add Storage ANE
  2. Init Storage ANE
  3. Upload Files to Storage
  4. Download Files to Air
  5. Use File Metadata
  6. Delete Files

Get Started with Functions

  1. Write & Deploy Functions
  2. Add Functions ANE
  3. Init Functions
Clone this wiki locally