Skip to content

Commit 473c9d1

Browse files
docs: add Database guide
1 parent 871233d commit 473c9d1

File tree

2 files changed

+333
-1
lines changed

2 files changed

+333
-1
lines changed

docs/guide/database.rst

Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
1+
Database
2+
========
3+
4+
You can build paths to your data by using the ``child()`` method.
5+
6+
.. code-block:: python
7+
8+
db = firebaseApp.database()
9+
db.child("users").child("Morty")
10+
..
11+
12+
.. note::
13+
Each of the following methods accepts a user token:
14+
``get()``, ``push()``, ``set()``, ``update()``,
15+
``remove()`` and ``stream()``.
16+
17+
18+
Save Data
19+
---------
20+
21+
22+
push
23+
^^^^
24+
25+
To save data with a unique, auto-generated, timestamp-based key, use the
26+
``push()`` method.
27+
28+
.. code-block:: python
29+
30+
data = {"name": "Mortimer 'Morty' Smith"}
31+
db.child("users").push(data)
32+
..
33+
34+
set
35+
^^^
36+
37+
To create your own keys use the ``set()`` method. The key in the example
38+
below is "Morty".
39+
40+
.. code-block:: python
41+
42+
data = {"name": "Mortimer 'Morty' Smith"}
43+
db.child("users").child("Morty").set(data)
44+
..
45+
46+
update
47+
^^^^^^
48+
49+
To update data for an existing entry use the ``update()`` method.
50+
51+
.. code-block:: python
52+
53+
db.child("users").child("Morty").update({"name": "Mortiest Morty"})
54+
..
55+
56+
remove
57+
^^^^^^
58+
59+
To delete data for an existing entry use the ``remove()`` method.
60+
61+
.. code-block:: python
62+
63+
db.child("users").child("Morty").remove()
64+
..
65+
66+
multi-location updates
67+
^^^^^^^^^^^^^^^^^^^^^^
68+
69+
You can also perform `multi-location
70+
updates <https://www.firebase.com/blog/2015-09-24-atomic-writes-and-more.html>`__
71+
with the ``update()`` method.
72+
73+
.. code-block:: python
74+
75+
data = {
76+
"users/Morty/": {
77+
"name": "Mortimer 'Morty' Smith"
78+
},
79+
"users/Rick/": {
80+
"name": "Rick Sanchez"
81+
}
82+
}
83+
84+
db.update(data)
85+
..
86+
87+
To perform multi-location writes to new locations we can use the
88+
``generate_key()`` method.
89+
90+
.. code-block:: python
91+
92+
data = {
93+
"users/"+ref.generate_key(): {
94+
"name": "Mortimer 'Morty' Smith"
95+
},
96+
"users/"+ref.generate_key(): {
97+
"name": "Rick Sanchez"
98+
}
99+
}
100+
101+
db.update(data)
102+
..
103+
104+
105+
Retrieve Data
106+
-------------
107+
108+
109+
val
110+
^^^
111+
112+
Queries return a PyreResponse object. Calling ``val()`` on these objects
113+
returns the query data.
114+
115+
.. code-block:: python
116+
117+
users = db.child("users").get()
118+
print(users.val()) # {"Morty": {"name": "Mortimer 'Morty' Smith"}, "Rick": {"name": "Rick Sanchez"}}
119+
..
120+
121+
key
122+
^^^
123+
124+
Calling ``key()`` returns the key for the query data.
125+
126+
.. code-block:: python
127+
128+
user = db.child("users").get()
129+
print(user.key()) # users
130+
..
131+
132+
each
133+
^^^^
134+
135+
Returns a list of objects on each of which you can call ``val()`` and
136+
``key()``.
137+
138+
.. code-block:: python
139+
140+
all_users = db.child("users").get()
141+
for user in all_users.each():
142+
print(user.key()) # Morty
143+
print(user.val()) # {name": "Mortimer 'Morty' Smith"}
144+
..
145+
146+
get
147+
^^^
148+
149+
To return data from a path simply call the ``get()`` method.
150+
151+
.. code-block:: python
152+
153+
all_users = db.child("users").get()
154+
..
155+
156+
Conditional Requests
157+
^^^^^^^^^^^^^^^^^^^^
158+
159+
It's possible to do conditional sets and removes by using the
160+
``conditional_set()`` and ``conitional_remove()`` methods respectively.
161+
You can read more about conditional requests in Firebase
162+
`here <https://firebase.google.com/docs/reference/rest/database/#section-conditional-requests>`__.
163+
164+
To use these methods, you first get the ETag of a particular path by
165+
using the ``get_etag()`` method. You can then use that tag in your
166+
conditional request.
167+
168+
.. code-block:: python
169+
170+
etag = db.child("users").child("Morty").get_etag()
171+
data = {"name": "Mortimer 'Morty' Smith"}
172+
db.child("users").child("Morty").conditional_set(data, etag)
173+
..
174+
175+
If the passed ETag does not match the ETag of the path in the database,
176+
the data will not be written, and both conditional request methods will
177+
return a single key-value pair with the new ETag to use of the following
178+
form:
179+
180+
.. code-block:: json
181+
182+
{ "ETag": "8KnE63B6HiKp67Wf3HQrXanujSM=" }
183+
..
184+
185+
Here's an example of checking whether or not a conditional removal was
186+
successful:
187+
188+
.. code-block:: python
189+
190+
etag = db.child("users").child("Morty").get_etag()
191+
response = db.child("users").child("Morty").conditional_remove(etag)
192+
193+
if "ETag" in response:
194+
etag = response["ETag"] # our ETag was out-of-date
195+
else:
196+
print("We removed the data successfully!")
197+
..
198+
199+
shallow
200+
^^^^^^^
201+
202+
To return just the keys at a particular path use the ``shallow()``
203+
method.
204+
205+
.. code-block:: python
206+
207+
all_user_ids = db.child("users").shallow().get()
208+
..
209+
210+
.. note::
211+
``shallow()`` can not be used in conjunction with any complex
212+
queries.
213+
214+
streaming
215+
^^^^^^^^^
216+
217+
You can listen to live changes to your data with the ``stream()``
218+
method.
219+
220+
.. code-block:: python
221+
222+
def stream_handler(message):
223+
print(message["event"]) # put
224+
print(message["path"]) # /-K7yGTTEp7O549EzTYtI
225+
print(message["data"]) # {'title': 'Firebase', "body": "etc..."}
226+
227+
my_stream = db.child("posts").stream(stream_handler)
228+
..
229+
230+
You should at least handle ``put`` and ``patch`` events. Refer to
231+
`"Streaming from the REST
232+
API" <https://firebase.google.com/docs/reference/rest/database/#section-streaming>`__
233+
for details.
234+
235+
You can also add a ``stream_id`` to help you identify a stream if you
236+
have multiple running:
237+
238+
.. code-block:: python
239+
240+
my_stream = db.child("posts").stream(stream_handler, stream_id="new_posts")
241+
..
242+
243+
close the stream
244+
^^^^^^^^^^^^^^^^
245+
246+
.. code-block:: python
247+
248+
my_stream.close()
249+
..
250+
251+
252+
Complex Queries
253+
---------------
254+
255+
Queries can be built by chaining multiple query parameters together.
256+
257+
.. code-block:: python
258+
259+
users_by_name = db.child("users").order_by_child("name").limit_to_first(3).get()
260+
..
261+
262+
This query will return the first three users ordered by name.
263+
264+
order_by_child
265+
^^^^^^^^^^^^^^
266+
267+
We begin any complex query with ``order_by_child()``.
268+
269+
.. code-block:: python
270+
271+
users_by_name = db.child("users").order_by_child("name").get()
272+
..
273+
274+
This query will return users ordered by name.
275+
276+
equal_to
277+
^^^^^^^^
278+
279+
Return data with a specific value.
280+
281+
.. code-block:: python
282+
283+
users_by_score = db.child("users").order_by_child("score").equal_to(10).get()
284+
..
285+
286+
This query will return users with a score of 10.
287+
288+
start_at and end_at
289+
^^^^^^^^^^^^^^^^^^^
290+
291+
Specify a range in your data.
292+
293+
.. code-block:: python
294+
295+
users_by_score = db.child("users").order_by_child("score").start_at(3).end_at(10).get()
296+
..
297+
298+
This query returns users ordered by score and with a score between 3 and
299+
10.
300+
301+
limit_to_first and limit_to_last
302+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
303+
304+
Limits data returned.
305+
306+
.. code-block:: python
307+
308+
users_by_score = db.child("users").order_by_child("score").limit_to_first(5).get()
309+
..
310+
311+
This query returns the first five users ordered by score.
312+
313+
order_by_key
314+
^^^^^^^^^^^^
315+
316+
When using ``order_by_key()`` to sort your data, data is returned in
317+
ascending order by key.
318+
319+
.. code-block:: python
320+
321+
users_by_key = db.child("users").order_by_key().get()
322+
..
323+
324+
order_by_value
325+
^^^^^^^^^^^^^^
326+
327+
When using ``order_by_value()``, children are ordered by their value.
328+
329+
.. code-block:: python
330+
331+
users_by_value = db.child("users").order_by_value().get()
332+
..

docs/guide/firebase-rest-api.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ A Firebase app can use multiple Firebase services.
124124

125125
``firebaseApp.auth()`` - :ref:`Authentication<guide/authentication:Authentication>`
126126

127-
``firebaseApp.database()`` - `Database`
127+
``firebaseApp.database()`` - :ref:`Database<guide/database:Database>`
128128

129129
``firebaseApp.storage()`` - `Storage`
130130

0 commit comments

Comments
 (0)