Skip to content

Commit e0245f6

Browse files
samtsternkurtisvg
authored andcommitted
Snippets and tests for Firestore listens (#995)
* Snippets and tests for Firestore listens * Fix comment block Change-Id: Iab845387ba4188334abd75e7ae0d84bcc3f2f6f9 * Update to 0.33 SDK Change-Id: I9880508d0ac60cc886df940c43b4d720c129ce2f * Fix checkstyle issues Change-Id: Id5074a918a89ba8162b839f01ee213b607dc685b * Suppress name warning Change-Id: If24e4daa22b2581e93d50106f65cbc16ad583d0c
1 parent d450027 commit e0245f6

11 files changed

+396
-86
lines changed

firestore/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
<dependency>
4646
<groupId>com.google.cloud</groupId>
4747
<artifactId>google-cloud-firestore</artifactId>
48-
<version>0.32.0-beta</version>
48+
<version>0.33.0-beta</version>
4949
</dependency>
5050
<!-- [END fs-maven] -->
5151

firestore/src/main/java/com/example/firestore/Quickstart.java

+5-6
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,14 @@
1818

1919
import com.google.api.core.ApiFuture;
2020
import com.google.cloud.firestore.DocumentReference;
21-
import com.google.cloud.firestore.DocumentSnapshot;
2221
// [START fs_include_dependencies]
2322
import com.google.cloud.firestore.Firestore;
2423
import com.google.cloud.firestore.FirestoreOptions;
2524
// [END fs_include_dependencies]
25+
import com.google.cloud.firestore.QueryDocumentSnapshot;
2626
import com.google.cloud.firestore.QuerySnapshot;
2727
import com.google.cloud.firestore.WriteResult;
2828
import com.google.common.collect.ImmutableMap;
29-
3029
import java.util.HashMap;
3130
import java.util.List;
3231
import java.util.Map;
@@ -126,8 +125,8 @@ void runAQuery() throws Exception {
126125
// ...
127126
// query.get() blocks on response
128127
QuerySnapshot querySnapshot = query.get();
129-
List<DocumentSnapshot> documents = querySnapshot.getDocuments();
130-
for (DocumentSnapshot document : documents) {
128+
List<QueryDocumentSnapshot> documents = querySnapshot.getDocuments();
129+
for (QueryDocumentSnapshot document : documents) {
131130
System.out.println("User: " + document.getId());
132131
System.out.println("First: " + document.getString("first"));
133132
if (document.contains("middle")) {
@@ -146,8 +145,8 @@ void retrieveAllDocuments() throws Exception {
146145
// ...
147146
// query.get() blocks on response
148147
QuerySnapshot querySnapshot = query.get();
149-
List<DocumentSnapshot> documents = querySnapshot.getDocuments();
150-
for (DocumentSnapshot document : documents) {
148+
List<QueryDocumentSnapshot> documents = querySnapshot.getDocuments();
149+
for (QueryDocumentSnapshot document : documents) {
151150
System.out.println("User: " + document.getId());
152151
System.out.println("First: " + document.getString("first"));
153152
if (document.contains("middle")) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
/*
2+
* Copyright 2018 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.firestore.snippets;
18+
19+
import com.google.api.core.SettableApiFuture;
20+
import com.google.cloud.firestore.DocumentChange;
21+
import com.google.cloud.firestore.DocumentChange.Type;
22+
import com.google.cloud.firestore.DocumentReference;
23+
import com.google.cloud.firestore.DocumentSnapshot;
24+
import com.google.cloud.firestore.EventListener;
25+
import com.google.cloud.firestore.Firestore;
26+
import com.google.cloud.firestore.FirestoreException;
27+
import com.google.cloud.firestore.ListenerRegistration;
28+
import com.google.cloud.firestore.Query;
29+
import com.google.cloud.firestore.QuerySnapshot;
30+
import java.util.ArrayList;
31+
import java.util.List;
32+
import java.util.Map;
33+
import java.util.concurrent.TimeUnit;
34+
import javax.annotation.Nullable;
35+
36+
/**
37+
* Snippets to demonstrate Firestore 'listen' operations.
38+
*/
39+
@SuppressWarnings("Convert2Lambda")
40+
public class ListenDataSnippets {
41+
42+
private static final long TIMEOUT_SECONDS = 5;
43+
44+
private final Firestore db;
45+
46+
ListenDataSnippets(Firestore db) {
47+
this.db = db;
48+
}
49+
50+
/**
51+
* Listen to a single document, returning data after the first snapshot.
52+
*/
53+
Map<String, Object> listenToDocument() throws Exception {
54+
final SettableApiFuture<Map<String, Object>> future = SettableApiFuture.create();
55+
56+
// [START listen_to_document]
57+
DocumentReference docRef = db.collection("cities").document("SF");
58+
docRef.addSnapshotListener(new EventListener<DocumentSnapshot>() {
59+
@Override
60+
public void onEvent(@Nullable DocumentSnapshot snapshot,
61+
@Nullable FirestoreException e) {
62+
if (e != null) {
63+
System.err.println("Listen failed: " + e);
64+
return;
65+
}
66+
67+
if (snapshot != null && snapshot.exists()) {
68+
System.out.println("Current data: " + snapshot.getData());
69+
} else {
70+
System.out.print("Current data: null");
71+
}
72+
// [START_EXCLUDE silent]
73+
if (!future.isDone()) {
74+
future.set(snapshot.getData());
75+
}
76+
// [END_EXCLUDE]
77+
}
78+
});
79+
// [END listen_to_document]
80+
81+
return future.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
82+
}
83+
84+
/**
85+
* Listen to a query, returning the names of all cities in the first snapshot.
86+
*/
87+
List<String> listenForMultiple() throws Exception {
88+
final SettableApiFuture<List<String>> future = SettableApiFuture.create();
89+
90+
// [START listen_to_multiple]
91+
db.collection("cities")
92+
.whereEqualTo("state", "CA")
93+
.addSnapshotListener(new EventListener<QuerySnapshot>() {
94+
@Override
95+
public void onEvent(@Nullable QuerySnapshot snapshots,
96+
@Nullable FirestoreException e) {
97+
if (e != null) {
98+
System.err.println("Listen failed:" + e);
99+
return;
100+
}
101+
102+
List<String> cities = new ArrayList<>();
103+
for (DocumentSnapshot doc : snapshots) {
104+
if (doc.get("name") != null) {
105+
cities.add(doc.getString("name"));
106+
}
107+
}
108+
System.out.println("Current cites in CA: " + cities);
109+
// [START_EXCLUDE silent]
110+
if (!future.isDone()) {
111+
future.set(cities);
112+
}
113+
// [END_EXCLUDE]
114+
}
115+
});
116+
// [END listen_to_multiple]
117+
118+
return future.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
119+
}
120+
121+
/**
122+
* Listen to a query, returning the list of DocumentChange events in the first snapshot.
123+
*/
124+
List<DocumentChange> listenForChanges() throws Exception {
125+
SettableApiFuture<List<DocumentChange>> future = SettableApiFuture.create();
126+
127+
// [START listen_for_changes]
128+
db.collection("cities")
129+
.whereEqualTo("state", "CA")
130+
.addSnapshotListener(new EventListener<QuerySnapshot>() {
131+
@Override
132+
public void onEvent(@Nullable QuerySnapshot snapshots,
133+
@Nullable FirestoreException e) {
134+
if (e != null) {
135+
System.err.println("Listen failed: " + e);
136+
return;
137+
}
138+
139+
for (DocumentChange dc : snapshots.getDocumentChanges()) {
140+
switch (dc.getType()) {
141+
case ADDED:
142+
System.out.println("New city: " + dc.getDocument().getData());
143+
break;
144+
case MODIFIED:
145+
System.out.println("Modified city: " + dc.getDocument().getData());
146+
break;
147+
case REMOVED:
148+
System.out.println("Removed city: " + dc.getDocument().getData());
149+
break;
150+
default:
151+
break;
152+
}
153+
}
154+
// [START_EXCLUDE silent]
155+
if (!future.isDone()) {
156+
future.set(snapshots.getDocumentChanges());
157+
}
158+
// [END_EXCLUDE]
159+
}
160+
});
161+
// [END listen_for_changes]
162+
163+
return future.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
164+
}
165+
166+
/**
167+
* Demonstrate how to detach an event listener.
168+
*/
169+
void detachListener() {
170+
// [START detach_errors]
171+
Query query = db.collection("cities");
172+
ListenerRegistration registration = query.addSnapshotListener(
173+
new EventListener<QuerySnapshot>() {
174+
// [START_EXCLUDE]
175+
@Override
176+
public void onEvent(@Nullable QuerySnapshot snapshots,
177+
@Nullable FirestoreException e) {
178+
179+
}
180+
// [END_EXCLUDE]
181+
});
182+
183+
// ...
184+
185+
// Stop listening to changes
186+
registration.remove();
187+
// [END detach_errors]
188+
}
189+
190+
/**
191+
* Demonstrate how to handle listening errors.
192+
*/
193+
void listenErrors() {
194+
// [START listen_errors]
195+
db.collection("cities")
196+
.addSnapshotListener(new EventListener<QuerySnapshot>() {
197+
@Override
198+
public void onEvent(@Nullable QuerySnapshot snapshots,
199+
@Nullable FirestoreException e) {
200+
if (e != null) {
201+
System.err.println("Listen failed: " + e);
202+
return;
203+
}
204+
205+
for (DocumentChange dc : snapshots.getDocumentChanges()) {
206+
if (dc.getType() == Type.ADDED) {
207+
System.out.println("New city: " + dc.getDocument().getData());
208+
}
209+
}
210+
}
211+
});
212+
// [END listen_errors]
213+
}
214+
215+
}

firestore/src/main/java/com/example/firestore/snippets/ManageDataSnippets.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.google.cloud.firestore.DocumentSnapshot;
2424
import com.google.cloud.firestore.FieldValue;
2525
import com.google.cloud.firestore.Firestore;
26+
import com.google.cloud.firestore.QueryDocumentSnapshot;
2627
import com.google.cloud.firestore.QuerySnapshot;
2728
import com.google.cloud.firestore.SetOptions;
2829
import com.google.cloud.firestore.Transaction;
@@ -294,8 +295,8 @@ void deleteCollection(CollectionReference collection, int batchSize) {
294295
ApiFuture<QuerySnapshot> future = collection.limit(batchSize).get();
295296
int deleted = 0;
296297
// future.get() blocks on document retrieval
297-
List<DocumentSnapshot> documents = future.get().getDocuments();
298-
for (DocumentSnapshot document : documents) {
298+
List<QueryDocumentSnapshot> documents = future.get().getDocuments();
299+
for (QueryDocumentSnapshot document : documents) {
299300
document.getReference().delete();
300301
++deleted;
301302
}

firestore/src/main/java/com/example/firestore/snippets/RetrieveDataSnippets.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.google.cloud.firestore.DocumentReference;
2525
import com.google.cloud.firestore.DocumentSnapshot;
2626
import com.google.cloud.firestore.Firestore;
27+
import com.google.cloud.firestore.QueryDocumentSnapshot;
2728
import com.google.cloud.firestore.QuerySnapshot;
2829
import com.google.cloud.firestore.WriteResult;
2930

@@ -106,13 +107,13 @@ public City getDocumentAsEntity() throws Exception {
106107
*
107108
* @return list of documents of capital cities.
108109
*/
109-
public List<DocumentSnapshot> getQueryResults() throws Exception {
110+
public List<QueryDocumentSnapshot> getQueryResults() throws Exception {
110111
// [START fs_get_multiple_docs]
111112
//asynchronously retrieve multiple documents
112113
ApiFuture<QuerySnapshot> future =
113114
db.collection("cities").whereEqualTo("capital", true).get();
114115
// future.get() blocks on response
115-
List<DocumentSnapshot> documents = future.get().getDocuments();
116+
List<QueryDocumentSnapshot> documents = future.get().getDocuments();
116117
for (DocumentSnapshot document : documents) {
117118
System.out.println(document.getId() + " => " + document.toObject(City.class));
118119
}
@@ -125,13 +126,13 @@ public List<DocumentSnapshot> getQueryResults() throws Exception {
125126
*
126127
* @return list of documents
127128
*/
128-
public List<DocumentSnapshot> getAllDocuments() throws Exception {
129+
public List<QueryDocumentSnapshot> getAllDocuments() throws Exception {
129130
// [START fs_get_all_docs]
130131
//asynchronously retrieve all documents
131132
ApiFuture<QuerySnapshot> future = db.collection("cities").get();
132133
// future.get() blocks on response
133-
List<DocumentSnapshot> documents = future.get().getDocuments();
134-
for (DocumentSnapshot document : documents) {
134+
List<QueryDocumentSnapshot> documents = future.get().getDocuments();
135+
for (QueryDocumentSnapshot document : documents) {
135136
System.out.println(document.getId() + " => " + document.toObject(City.class));
136137
}
137138
// [END fs_get_all_docs]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright 2018 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.firestore;
18+
19+
import com.example.firestore.snippets.ManageDataSnippetsIT;
20+
import com.example.firestore.snippets.model.City;
21+
import com.google.api.core.ApiFuture;
22+
import com.google.cloud.firestore.DocumentReference;
23+
import com.google.cloud.firestore.DocumentSnapshot;
24+
import com.google.cloud.firestore.Firestore;
25+
import com.google.cloud.firestore.FirestoreOptions;
26+
import com.google.cloud.firestore.QuerySnapshot;
27+
import java.util.Map;
28+
import org.junit.BeforeClass;
29+
30+
/**
31+
* Base class for tests like {@link ManageDataSnippetsIT}.
32+
*/
33+
public class BaseIntegrationTest {
34+
35+
protected static String projectId = "java-docs-samples-firestore";
36+
protected static Firestore db;
37+
38+
@BeforeClass
39+
public static void baseSetup() throws Exception {
40+
FirestoreOptions firestoreOptions = FirestoreOptions.getDefaultInstance().toBuilder()
41+
.setProjectId(projectId)
42+
.build();
43+
db = firestoreOptions.getService();
44+
deleteAllDocuments(db);
45+
}
46+
47+
protected DocumentSnapshot getDocumentData(DocumentReference docRef) throws Exception {
48+
return docRef.get().get();
49+
}
50+
51+
protected Map<String, Object> getDocumentDataAsMap(DocumentReference docRef) throws Exception {
52+
DocumentSnapshot snapshot = docRef.get().get();
53+
if (!snapshot.exists()) {
54+
throw new RuntimeException("Document does not exist: " + docRef.getPath());
55+
}
56+
57+
return snapshot.getData();
58+
}
59+
60+
protected City getDocumentDataAsCity(DocumentReference docRef) throws Exception {
61+
return docRef.get().get().toObject(City.class);
62+
}
63+
64+
protected static void deleteAllDocuments(Firestore db) throws Exception {
65+
ApiFuture<QuerySnapshot> future = db.collection("cities").get();
66+
QuerySnapshot querySnapshot = future.get();
67+
for (DocumentSnapshot doc : querySnapshot.getDocuments()) {
68+
// block on delete operation
69+
db.collection("cities").document(doc.getId()).delete().get();
70+
}
71+
}
72+
73+
}

0 commit comments

Comments
 (0)