Skip to content

Commit eab7d78

Browse files
authored
Add Firestore docs (#11)
1 parent 7d72ddb commit eab7d78

File tree

3 files changed

+237
-12
lines changed

3 files changed

+237
-12
lines changed

README.md

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
[![Build Status](https://travis-ci.org/firebase/FirebaseUI-Android.svg?branch=master)](https://travis-ci.org/firebase/FirebaseUI-Android)
44

55
FirebaseUI is an open-source library for Android that allows you to
6-
quickly connect common UI elements to [Firebase](https://firebase.google.com)
7-
APIs like the Realtime Database or Firebase Authentication.
6+
quickly connect common UI elements to [Firebase](https://firebase.google.com) APIs.
87

98
A compatible FirebaseUI client is also available for [iOS](https://github.com/firebase/firebaseui-ios).
109

@@ -19,10 +18,11 @@ A compatible FirebaseUI client is also available for [iOS](https://github.com/fi
1918

2019
## Usage
2120

22-
FirebaseUI has separate modules for using Firebase Database, Auth, and Storage. To
23-
get started, see the individual instructions for each module:
21+
FirebaseUI has separate modules for using Firebase Realtime Database, Cloud Firestore,
22+
Firebase Auth, and Cloud Storage. To get started, see the individual instructions for each module:
2423

2524
* [firebase-ui-database](database/README.md)
25+
* [firebase-ui-firestore](firestore/README.md)
2626
* [firebase-ui-auth](auth/README.md)
2727
* [firebase-ui-storage](storage/README.md)
2828

@@ -38,17 +38,17 @@ libraries.
3838

3939
```groovy
4040
dependencies {
41-
// FirebaseUI Database only
41+
// FirebaseUI for Firebase Realtime Database
4242
compile 'com.firebaseui:firebase-ui-database:2.3.0'
43+
44+
// FirebaseUI for Cloud Firestore
45+
compile 'com.firebaseui:firebase-ui-firestore:2.3.0'
4346
44-
// FirebaseUI Auth only
47+
// FirebaseUI for Firebase Auth
4548
compile 'com.firebaseui:firebase-ui-auth:2.3.0'
4649
47-
// FirebaseUI Storage only
50+
// FirebaseUI for Cloud Storage
4851
compile 'com.firebaseui:firebase-ui-storage:2.3.0'
49-
50-
// Single target that includes all FirebaseUI libraries above
51-
compile 'com.firebaseui:firebase-ui:2.3.0'
5252
}
5353
```
5454

@@ -78,6 +78,9 @@ firebase-ui-auth
7878
firebase-ui-database
7979
|--- com.google.firebase:firebase-database
8080
81+
firebase-ui-firestore
82+
|--- com.google.firebase:firebase-firestore
83+
8184
firebase-ui-storage
8285
|--- com.google.firebase:firebase-storage
8386
```
@@ -120,7 +123,7 @@ compile "com.android.support:customtabs:$BAR"
120123
compile "com.android.support:cardview-v7:$BAR"
121124
```
122125

123-
Database:
126+
Realtime Database:
124127

125128
```groovy
126129
compile "com.google.firebase:firebase-database:$FOO"
@@ -129,6 +132,15 @@ compile "com.android.support:recyclerview-v7:$BAR"
129132
compile "com.android.support:support-v4:$BAR"
130133
```
131134

135+
Firestore:
136+
137+
```groovy
138+
compile "com.google.firebase:firebase-firestore:$FOO"
139+
140+
compile "com.android.support:recyclerview-v7:$BAR"
141+
compile "com.android.support:support-v4:$BAR"
142+
```
143+
132144
Storage:
133145

134146
```groovy

database/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# FirebaseUI Database
1+
# FirebaseUI for Realtime Database
22

33
## Using FirebaseUI to populate a [`RecyclerView`](https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html)
44

firestore/README.md

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
# FirebaseUI for Cloud Firestore
2+
3+
FirebaseUI makes it simple to bind data from Cloud Firestore to your app's UI.
4+
5+
Before using this library, you should be familiar with the following topics:
6+
7+
* [Structuring and querying data in Cloud Firestore][firestore-docs].
8+
* [Displaying lists of data using a RecyclerView][recyclerview].
9+
10+
## Using FirebaseUI to populate a `RecyclerView`
11+
12+
### Data Model
13+
14+
Imagine you have a chat app where each chat message is a document in the `chats` collection
15+
of your database. In your app, you may represent a chat message like this:
16+
17+
```java
18+
public class Chat {
19+
20+
private String mName;
21+
private String mMessage;
22+
private String mUid;
23+
private Date mTimestamp;
24+
25+
public Chat() { } // Needed for Firebase
26+
27+
public Chat(String name, String message, String uid) {
28+
mName = name;
29+
mMessage = message;
30+
mUid = uid;
31+
}
32+
33+
public String getName() { return mName; }
34+
35+
public void setName(String name) { mName = name; }
36+
37+
public String getMessage() { return mMessage; }
38+
39+
public void setMessage(String message) { mMessage = message; }
40+
41+
public String getUid() { return mUid; }
42+
43+
public void setUid(String uid) { mUid = uid; }
44+
45+
@ServerTimestamp
46+
public Date getTimestamp() { return mTimestamp; }
47+
48+
public void setTimestamp(Date timestamp) { mTimestamp = timestamp; }
49+
}
50+
```
51+
52+
A few things to note about this model class:
53+
54+
* The getters and setters follow the JavaBean naming pattern which allows Firestore to map
55+
the data to field names (ex: `getName()` provides the `name` field).
56+
* The class has an empty constructor, which is required for Firestore's automatic data mapping.
57+
58+
For a properly constructed model class like the `Chat` class above, Firestore can perform automatic
59+
serialization in `DocumentReference#set()` and automatic deserialization in
60+
`DocumentSnapshot#toObject()`. For more information on data mapping in Firestore, see the
61+
documentation on [custom objects][firestore-custom-objects].
62+
63+
### Querying
64+
65+
On the main screen of your app, you may want to show the 50 most recent chat messages.
66+
In Firestore, you would use the following query:
67+
68+
```java
69+
Query query = FirebaseFirestore.getInstance()
70+
.collection("chats")
71+
.orderBy("timestamp")
72+
.limit(50);
73+
```
74+
75+
To retrieve this data without FirebaseUI, you might use `addSnapshotListener` to listen for
76+
live query updates:
77+
78+
```java
79+
query.addSnapshotListener(new EventListener<QuerySnapshot>() {
80+
@Override
81+
public void onEvent(@Nullable QuerySnapshot snapshot,
82+
@Nullable FirebaseFirestoreException e) {
83+
if (e != null) {
84+
// Handle error
85+
//...
86+
return;
87+
}
88+
89+
// Convert query snapshot to a list of chats
90+
List<Chat> chats = snapshot.toObjects(Chat.class);
91+
92+
// Update UI
93+
// ...
94+
}
95+
});
96+
```
97+
98+
If you're displaying a list of data, you likely want to bind the `Chat` objects to a
99+
`RecyclerView`. This means implementing a custom `RecyclerView.Adapter` and coordinating
100+
updates with the `EventListener` on the `Query`.
101+
102+
Fear not, FirebaseUI does all of this for you automatically!
103+
104+
### Using the FirestoreRecyclerAdapter
105+
106+
The `FirestoreRecyclerAdapter` binds a `Query` to a `RecyclerView`. When documents are added,
107+
removed, or change these updates are automatically applied to your UI in real time.
108+
109+
First, configure the adapter by building `FirestoreRecyclerOptions`. In this case we will continue
110+
with our chat example:
111+
112+
```java
113+
// Configure recycler adapter options:
114+
// * query is the Query object defined above.
115+
// * Chat.class instructs the adapter to convert each DocumentSnapshot to a Chat object
116+
FirestoreRecyclerOptions<Chat> options = new FirestoreRecyclerOptions.Builder<Chat>()
117+
.setQuery(query, Chat.class)
118+
.build();
119+
```
120+
121+
Next create the `FirestoreRecyclerAdapter` object. You should already have a `ViewHolder` subclass
122+
for displaying each item. In this case we will use a custom `ChatHolder` class:
123+
124+
```java
125+
FirestoreRecyclerAdapter adapter = new FirestoreRecyclerAdapter<Chat, ChatHolder>(options) {
126+
@Override
127+
public void onBindViewHolder(ChatHolder holder, int position, Chat model) {
128+
// Bind the Chat object to the ChatHolder
129+
// ...
130+
}
131+
132+
@Override
133+
public ChatHolder onCreateViewHolder(ViewGroup group, int i) {
134+
// Create a new instance of the ViewHolder, in this case we are using a custom
135+
// layout called R.layout.message for each item
136+
View view = LayoutInflater.from(group.getContext())
137+
.inflate(R.layout.message, group, false);
138+
139+
return new ChatHolder(view);
140+
}
141+
};
142+
```
143+
144+
Finally attach the adapter to your `RecyclerView` with the `RecyclerView#setAdapter()`.
145+
Don't forget to also set a `LayoutManager`!
146+
147+
### FirestoreRecyclerAdapter lifecycle
148+
149+
### Start/stop listening
150+
151+
The `FirestoreRecyclerAdapter` uses a snapshot listener to monitor changes to the Firestore query.
152+
To begin listening for data, call the `startListening()` method. You may want to call this
153+
in your `onStart()` method. Make sure you have finished any authentication necessary to read the
154+
data before calling `startListening()` or your query will fail.
155+
156+
```java
157+
@Override
158+
protected void onStart() {
159+
super.onStart();
160+
adapter.startListening();
161+
}
162+
```
163+
164+
Similarly, the `stopListening()` call removes the snapshot listener and all data in the adapter.
165+
Call this method when the containing Activity or Fragment stops:
166+
167+
```java
168+
@Override
169+
protected void onStop() {
170+
super.onStop();
171+
adapter.stopListening();
172+
}
173+
```
174+
175+
If you don't want to manually start/stop listening you can use
176+
[Android Architecture Components][arch-components] to automatically manage the lifecycle of the
177+
`FirestoreRecyclerAdapter`. Pass a `LifecycleOwner` to
178+
`FirestoreRecyclerOptions.Builder#setLifecycleOwner(...)` and FirebaseUI will automatically
179+
start and stop listening in `onStart()` and `onStop()`.
180+
181+
### Data and error events
182+
183+
When using the `FirestoreRecyclerAdapter` you may want to perform some action every time data
184+
changes or when there is an error. To do this, override the `onDataChanged()` and `onError()`
185+
methods of the adapter:
186+
187+
```java
188+
FirestoreRecyclerAdapter adapter = new FirestoreRecyclerAdapter<Chat, ChatHolder>(options) {
189+
190+
// ...
191+
192+
@Override
193+
public void onDataChanged() {
194+
// Called each time there is a new query snapshot. You may want to use this method
195+
// to hide a loading spinner or check for the "no documents" state and update your UI.
196+
// ...
197+
}
198+
199+
@Override
200+
public void onError(FirebaseFirestoreException e) {
201+
// Called when there is an error getting a query snapshot. You may want to update
202+
// your UI to display an error message to the user.
203+
// ...
204+
}
205+
206+
}
207+
```
208+
209+
210+
[firestore-docs]: https://firebase.google.com/docs/firestore/
211+
[firestore-custom-objects]: https://firebase.google.com/docs/firestore/manage-data/add-data#custom_objects
212+
[recyclerview]: https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html
213+
[arch-components]: https://developer.android.com/topic/libraries/architecture/index.html

0 commit comments

Comments
 (0)