0
# Cloud Firestore
1
2
Firebase Cloud Firestore integration providing complete access to Google Cloud Firestore database operations including document and collection management, queries, transactions, and batch operations. All functionality from the Google Cloud Firestore client is available.
3
4
## Capabilities
5
6
### Client Access
7
8
Get a Firestore client instance for database operations with optional database ID specification for multi-database projects.
9
10
```python { .api }
11
def client(app=None, database_id=None):
12
"""
13
Return a client for interacting with the Cloud Firestore database.
14
15
Args:
16
app: Firebase app instance (optional)
17
database_id: Database ID for multi-database projects (optional)
18
19
Returns:
20
google.cloud.firestore.Client: Firestore client instance with full API access
21
"""
22
```
23
24
## Google Cloud Firestore Integration
25
26
The Firebase Admin SDK provides direct access to the complete Google Cloud Firestore client. All operations available in the `google.cloud.firestore` library are accessible through the client returned by the `client()` function.
27
28
### Core Operations Available
29
30
The Firestore client provides access to all standard Firestore operations:
31
32
- **Document Operations**: Create, read, update, delete individual documents
33
- **Collection Operations**: List, query, and manage document collections
34
- **Batch Operations**: Perform multiple operations atomically
35
- **Transaction Operations**: Execute operations within ACID transactions
36
- **Query Operations**: Complex filtering, ordering, and pagination
37
- **Real-time Listeners**: Subscribe to document and query changes
38
- **Security Rules**: Manage Firestore security rules
39
40
### Common Usage Patterns
41
42
#### Document Operations
43
44
```python
45
import firebase_admin
46
from firebase_admin import firestore
47
48
# Get Firestore client
49
db = firestore.client()
50
51
# Document reference
52
doc_ref = db.collection('users').document('user123')
53
54
# Create/Set document
55
doc_ref.set({
56
'name': 'John Doe',
57
'email': 'john@example.com',
58
'age': 30
59
})
60
61
# Get document
62
doc = doc_ref.get()
63
if doc.exists:
64
print(f'Document data: {doc.to_dict()}')
65
66
# Update document
67
doc_ref.update({
68
'age': 31,
69
'last_login': firestore.SERVER_TIMESTAMP
70
})
71
72
# Delete document
73
doc_ref.delete()
74
```
75
76
#### Collection and Query Operations
77
78
```python
79
# Collection reference
80
users_ref = db.collection('users')
81
82
# Add document with auto-generated ID
83
doc_ref = users_ref.add({
84
'name': 'Jane Smith',
85
'email': 'jane@example.com'
86
})
87
88
# Query collection
89
query = users_ref.where('age', '>=', 18).limit(10)
90
docs = query.stream()
91
92
for doc in docs:
93
print(f'{doc.id} => {doc.to_dict()}')
94
95
# Order and pagination
96
query = (users_ref
97
.order_by('name')
98
.limit(5))
99
100
results = query.get()
101
```
102
103
#### Batch Operations
104
105
```python
106
# Create batch
107
batch = db.batch()
108
109
# Add operations to batch
110
doc_ref1 = db.collection('users').document('user1')
111
batch.set(doc_ref1, {'name': 'User 1'})
112
113
doc_ref2 = db.collection('users').document('user2')
114
batch.update(doc_ref2, {'status': 'active'})
115
116
doc_ref3 = db.collection('users').document('user3')
117
batch.delete(doc_ref3)
118
119
# Commit batch
120
batch.commit()
121
```
122
123
#### Transactions
124
125
```python
126
from google.cloud.firestore import transactional
127
128
@transactional
129
def update_balance(transaction, account_ref, amount):
130
# Read current balance
131
account = account_ref.get(transaction=transaction)
132
current_balance = account.get('balance', 0)
133
134
# Update balance
135
new_balance = current_balance + amount
136
transaction.update(account_ref, {'balance': new_balance})
137
138
return new_balance
139
140
# Use transaction
141
account_ref = db.collection('accounts').document('account123')
142
transaction = db.transaction()
143
new_balance = update_balance(transaction, account_ref, 100)
144
```
145
146
#### Real-time Listeners
147
148
```python
149
def on_snapshot(doc_snapshot, changes, read_time):
150
for doc in doc_snapshot:
151
print(f'Received document snapshot: {doc.id}')
152
153
# Document listener
154
doc_ref = db.collection('users').document('user123')
155
doc_watch = doc_ref.on_snapshot(on_snapshot)
156
157
# Collection listener
158
def on_collection_snapshot(col_snapshot, changes, read_time):
159
for change in changes:
160
if change.type.name == 'ADDED':
161
print(f'New document: {change.document.id}')
162
elif change.type.name == 'MODIFIED':
163
print(f'Modified document: {change.document.id}')
164
elif change.type.name == 'REMOVED':
165
print(f'Removed document: {change.document.id}')
166
167
collection_watch = db.collection('users').on_snapshot(on_collection_snapshot)
168
169
# Stop listening
170
doc_watch.unsubscribe()
171
collection_watch.unsubscribe()
172
```
173
174
### Advanced Features
175
176
#### Sub-collections
177
178
```python
179
# Reference to sub-collection
180
subcollection_ref = (db.collection('users')
181
.document('user123')
182
.collection('orders'))
183
184
# Add document to sub-collection
185
subcollection_ref.add({
186
'product': 'Widget',
187
'quantity': 2,
188
'price': 29.99
189
})
190
191
# Query sub-collection
192
orders = subcollection_ref.where('price', '>', 20).get()
193
```
194
195
#### Field Transforms
196
197
```python
198
from google.cloud.firestore import Increment, ArrayUnion, ArrayRemove
199
200
# Increment numeric field
201
doc_ref.update({
202
'page_views': Increment(1)
203
})
204
205
# Array operations
206
doc_ref.update({
207
'tags': ArrayUnion(['new-tag']),
208
'old_tags': ArrayRemove(['old-tag'])
209
})
210
211
# Server timestamp
212
doc_ref.update({
213
'updated_at': firestore.SERVER_TIMESTAMP
214
})
215
```
216
217
#### Geographic Queries
218
219
```python
220
from google.cloud.firestore import GeoPoint
221
222
# Store location
223
doc_ref.set({
224
'name': 'Coffee Shop',
225
'location': GeoPoint(37.7749, -122.4194)
226
})
227
228
# Note: Geographic range queries require additional setup
229
# and are typically done using external libraries like GeoFire
230
```
231
232
## Multi-Database Support
233
234
For projects with multiple Firestore databases:
235
236
```python
237
# Default database
238
default_db = firestore.client()
239
240
# Named database
241
named_db = firestore.client(database_id='my-other-database')
242
243
# Use named database
244
doc_ref = named_db.collection('data').document('doc1')
245
doc_ref.set({'info': 'This is in the named database'})
246
```
247
248
## Error Handling
249
250
Firestore operations can raise various exceptions from the Google Cloud library:
251
252
```python
253
from google.cloud.exceptions import NotFound, PermissionDenied, FailedPrecondition
254
255
try:
256
doc = db.collection('users').document('nonexistent').get()
257
if not doc.exists:
258
print('Document does not exist')
259
except NotFound:
260
print('Collection or document path not found')
261
except PermissionDenied:
262
print('Insufficient permissions')
263
except FailedPrecondition as e:
264
print(f'Failed precondition: {e}')
265
```
266
267
## Performance Considerations
268
269
- **Batch Operations**: Use batch writes for multiple operations
270
- **Transaction Limits**: Transactions have size and time limits
271
- **Index Creation**: Complex queries may require composite indexes
272
- **Real-time Listeners**: Unsubscribe when no longer needed
273
- **Connection Pooling**: Reuse the same client instance
274
275
## Types
276
277
```python { .api }
278
# The client() function returns google.cloud.firestore.Client
279
# which provides access to all Firestore types and operations:
280
281
# Core types from google.cloud.firestore:
282
# - Client: Main Firestore client
283
# - CollectionReference: Reference to a collection
284
# - DocumentReference: Reference to a document
285
# - DocumentSnapshot: Document data snapshot
286
# - Query: Query builder
287
# - Transaction: Transaction context
288
# - WriteBatch: Batch operation builder
289
# - GeoPoint: Geographic point
290
# - SERVER_TIMESTAMP: Server timestamp sentinel
291
# - DELETE_FIELD: Field deletion sentinel
292
# - Increment: Numeric increment transform
293
# - ArrayUnion: Array union transform
294
# - ArrayRemove: Array remove transform
295
```