0
# Data Types & Field Values
1
2
Rich data model supporting various data types including custom Firestore types and special field operations.
3
4
## Capabilities
5
6
### Timestamp Operations
7
8
Represent precise timestamps with nanosecond accuracy, supporting server timestamps and date conversions.
9
10
```typescript { .api }
11
class Timestamp {
12
/**
13
* Current server timestamp
14
* @returns Timestamp representing current server time
15
*/
16
static now(): FirebaseFirestoreTypes.Timestamp;
17
18
/**
19
* Create timestamp from JavaScript Date
20
* @param date - Date object to convert
21
* @returns Timestamp representation of the date
22
*/
23
static fromDate(date: Date): FirebaseFirestoreTypes.Timestamp;
24
25
/**
26
* Create timestamp from milliseconds since epoch
27
* @param milliseconds - Milliseconds since Unix epoch
28
* @returns Timestamp representation
29
*/
30
static fromMillis(milliseconds: number): FirebaseFirestoreTypes.Timestamp;
31
32
/**
33
* Seconds component of the timestamp
34
*/
35
readonly seconds: number;
36
37
/**
38
* Nanoseconds component of the timestamp
39
*/
40
readonly nanoseconds: number;
41
42
/**
43
* Create a timestamp with specific seconds and nanoseconds
44
* @param seconds - Seconds since Unix epoch
45
* @param nanoseconds - Nanosecond component (0-999,999,999)
46
*/
47
constructor(seconds: number, nanoseconds: number);
48
49
/**
50
* Convert to JavaScript Date object
51
* @returns Date representation (may lose nanosecond precision)
52
*/
53
toDate(): Date;
54
55
/**
56
* Convert to milliseconds since epoch
57
* @returns Milliseconds representation
58
*/
59
toMillis(): number;
60
61
/**
62
* String representation of the timestamp
63
* @returns ISO 8601 string representation
64
*/
65
toString(): string;
66
67
/**
68
* JSON representation for serialization
69
* @returns Object with seconds and nanoseconds properties
70
*/
71
toJSON(): { seconds: number; nanoseconds: number };
72
73
/**
74
* Primitive value for comparison
75
* @returns String representation for comparison
76
*/
77
valueOf(): string;
78
79
/**
80
* Check if two timestamps are equal
81
* @param other - Other timestamp to compare
82
* @returns True if timestamps are equal
83
*/
84
isEqual(other: FirebaseFirestoreTypes.Timestamp): boolean;
85
}
86
```
87
88
**Usage Examples:**
89
90
```typescript
91
import firestore from '@react-native-firebase/firestore';
92
93
// Create timestamps
94
const now = firestore.Timestamp.now();
95
const specificTime = firestore.Timestamp.fromDate(new Date('2023-01-01'));
96
const fromMillis = firestore.Timestamp.fromMillis(Date.now());
97
const precise = new firestore.Timestamp(1672531200, 123456789); // 2023-01-01 with nanoseconds
98
99
// Use in document operations
100
await firestore().collection('events').add({
101
name: 'New Year Celebration',
102
startTime: firestore.Timestamp.fromDate(new Date('2023-01-01T00:00:00Z')),
103
endTime: firestore.Timestamp.fromDate(new Date('2023-01-01T02:00:00Z')),
104
registeredAt: firestore.Timestamp.now()
105
});
106
107
// Convert timestamps
108
const eventDoc = await firestore().collection('events').doc('eventId').get();
109
const eventData = eventDoc.data();
110
111
if (eventData) {
112
const startTime = eventData.startTime as firestore.Timestamp;
113
const startDate = startTime.toDate();
114
const startMillis = startTime.toMillis();
115
116
console.log('Event starts at:', startDate.toISOString());
117
console.log('Timestamp seconds:', startTime.seconds);
118
console.log('Timestamp nanoseconds:', startTime.nanoseconds);
119
}
120
```
121
122
### GeoPoint Operations
123
124
Represent geographic coordinates with latitude and longitude values.
125
126
```typescript { .api }
127
class GeoPoint {
128
/**
129
* Latitude coordinate (-90 to 90)
130
*/
131
readonly latitude: number;
132
133
/**
134
* Longitude coordinate (-180 to 180)
135
*/
136
readonly longitude: number;
137
138
/**
139
* Create a geographic point
140
* @param latitude - Latitude coordinate (-90 to 90)
141
* @param longitude - Longitude coordinate (-180 to 180)
142
*/
143
constructor(latitude: number, longitude: number);
144
145
/**
146
* Check if two geo points are equal
147
* @param other - Other GeoPoint to compare
148
* @returns True if coordinates are equal
149
*/
150
isEqual(other: FirebaseFirestoreTypes.GeoPoint): boolean;
151
152
/**
153
* JSON representation for serialization
154
* @returns Object with latitude and longitude properties
155
*/
156
toJSON(): { latitude: number; longitude: number };
157
}
158
```
159
160
**Usage Examples:**
161
162
```typescript
163
import firestore from '@react-native-firebase/firestore';
164
165
// Create GeoPoints
166
const newYork = new firestore.GeoPoint(40.7128, -74.0060);
167
const london = new firestore.GeoPoint(51.5074, -0.1278);
168
169
// Store locations in documents
170
await firestore().collection('locations').add({
171
name: 'Central Park',
172
coordinates: new firestore.GeoPoint(40.7829, -73.9654),
173
city: 'New York',
174
country: 'USA'
175
});
176
177
// Query by proximity (requires composite index)
178
const nearbyLocations = await firestore()
179
.collection('locations')
180
.where('coordinates', '>=', new firestore.GeoPoint(40.7, -74.1))
181
.where('coordinates', '<=', new firestore.GeoPoint(40.8, -73.9))
182
.get();
183
184
// Work with retrieved GeoPoints
185
const locationDoc = await firestore().collection('locations').doc('locationId').get();
186
const locationData = locationDoc.data();
187
188
if (locationData) {
189
const coordinates = locationData.coordinates as firestore.GeoPoint;
190
191
console.log('Latitude:', coordinates.latitude);
192
console.log('Longitude:', coordinates.longitude);
193
console.log('Coordinates JSON:', coordinates.toJSON());
194
195
// Check if coordinates match
196
const isNearCentralPark = coordinates.isEqual(new firestore.GeoPoint(40.7829, -73.9654));
197
}
198
```
199
200
### Field Value Operations
201
202
Special values for atomic field operations like server timestamps, increments, and array modifications.
203
204
```typescript { .api }
205
class FieldValue {
206
/**
207
* Server timestamp placeholder
208
* @returns FieldValue representing server timestamp
209
*/
210
static serverTimestamp(): FirebaseFirestoreTypes.FieldValue;
211
212
/**
213
* Field deletion marker
214
* @returns FieldValue that deletes the field
215
*/
216
static delete(): FirebaseFirestoreTypes.FieldValue;
217
218
/**
219
* Numeric increment operation
220
* @param n - Number to increment by (can be negative for decrement)
221
* @returns FieldValue that increments the field
222
*/
223
static increment(n: number): FirebaseFirestoreTypes.FieldValue;
224
225
/**
226
* Array union operation (adds elements not already present)
227
* @param elements - Elements to add to the array
228
* @returns FieldValue that performs array union
229
*/
230
static arrayUnion(...elements: any[]): FirebaseFirestoreTypes.FieldValue;
231
232
/**
233
* Array remove operation (removes all instances of elements)
234
* @param elements - Elements to remove from the array
235
* @returns FieldValue that performs array removal
236
*/
237
static arrayRemove(...elements: any[]): FirebaseFirestoreTypes.FieldValue;
238
239
/**
240
* Check if two field values are equal
241
* @param other - Other FieldValue to compare
242
* @returns True if field values are equal
243
*/
244
isEqual(other: FirebaseFirestoreTypes.FieldValue): boolean;
245
}
246
```
247
248
**Usage Examples:**
249
250
```typescript
251
import firestore from '@react-native-firebase/firestore';
252
253
// Server timestamps
254
await firestore().collection('posts').add({
255
title: 'Hello World',
256
content: 'This is my first post',
257
createdAt: firestore.FieldValue.serverTimestamp(),
258
updatedAt: firestore.FieldValue.serverTimestamp()
259
});
260
261
// Increment/decrement operations
262
await firestore().collection('counters').doc('pageViews').update({
263
count: firestore.FieldValue.increment(1)
264
});
265
266
await firestore().collection('users').doc('userId').update({
267
credits: firestore.FieldValue.increment(-10), // Deduct 10 credits
268
lastPurchaseAt: firestore.FieldValue.serverTimestamp()
269
});
270
271
// Array operations
272
await firestore().collection('users').doc('userId').update({
273
// Add tags (only if not already present)
274
tags: firestore.FieldValue.arrayUnion('premium', 'verified'),
275
276
// Remove tags (all instances)
277
blockedUsers: firestore.FieldValue.arrayRemove('spam-user-1', 'spam-user-2')
278
});
279
280
// Delete fields
281
await firestore().collection('users').doc('userId').update({
282
temporaryField: firestore.FieldValue.delete(),
283
updatedAt: firestore.FieldValue.serverTimestamp()
284
});
285
286
// Complex document update with multiple field values
287
await firestore().collection('products').doc('productId').update({
288
// Increment view count
289
viewCount: firestore.FieldValue.increment(1),
290
291
// Add to categories
292
categories: firestore.FieldValue.arrayUnion('featured'),
293
294
// Update timestamp
295
lastViewedAt: firestore.FieldValue.serverTimestamp(),
296
297
// Remove deprecated field
298
oldField: firestore.FieldValue.delete()
299
});
300
```
301
302
### Blob Operations
303
304
Handle binary data with base64 and Uint8Array conversions.
305
306
```typescript { .api }
307
class Blob {
308
/**
309
* Create blob from base64 string
310
* @param base64 - Base64 encoded string
311
* @returns Blob containing the decoded data
312
*/
313
static fromBase64String(base64: string): FirebaseFirestoreTypes.Blob;
314
315
/**
316
* Create blob from byte array
317
* @param array - Uint8Array containing raw bytes
318
* @returns Blob containing the byte data
319
*/
320
static fromUint8Array(array: Uint8Array): FirebaseFirestoreTypes.Blob;
321
322
/**
323
* Convert blob to base64 string
324
* @returns Base64 encoded representation
325
*/
326
toBase64(): string;
327
328
/**
329
* Convert blob to byte array
330
* @returns Uint8Array containing the raw bytes
331
*/
332
toUint8Array(): Uint8Array;
333
334
/**
335
* Check if two blobs are equal
336
* @param other - Other Blob to compare
337
* @returns True if blobs contain the same data
338
*/
339
isEqual(other: FirebaseFirestoreTypes.Blob): boolean;
340
}
341
```
342
343
**Usage Examples:**
344
345
```typescript
346
import firestore from '@react-native-firebase/firestore';
347
348
// Create blobs from different sources
349
const base64Data = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==';
350
const blobFromBase64 = firestore.Blob.fromBase64String(base64Data);
351
352
const byteArray = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]);
353
const blobFromBytes = firestore.Blob.fromUint8Array(byteArray);
354
355
// Store binary data in documents
356
await firestore().collection('files').add({
357
name: 'small-image.png',
358
mimeType: 'image/png',
359
size: 68,
360
data: blobFromBase64,
361
uploadedAt: firestore.FieldValue.serverTimestamp()
362
});
363
364
// Retrieve and work with blob data
365
const fileDoc = await firestore().collection('files').doc('fileId').get();
366
const fileData = fileDoc.data();
367
368
if (fileData) {
369
const blobData = fileData.data as firestore.Blob;
370
371
// Convert back to different formats
372
const base64String = blobData.toBase64();
373
const uint8Array = blobData.toUint8Array();
374
375
console.log('Base64:', base64String);
376
console.log('Byte array length:', uint8Array.length);
377
console.log('First byte:', uint8Array[0]);
378
}
379
380
// Compare blobs
381
const blob1 = firestore.Blob.fromBase64String('SGVsbG8='); // "Hello"
382
const blob2 = firestore.Blob.fromBase64String('SGVsbG8='); // "Hello"
383
const blob3 = firestore.Blob.fromBase64String('V29ybGQ='); // "World"
384
385
console.log('blob1 equals blob2:', blob1.isEqual(blob2)); // true
386
console.log('blob1 equals blob3:', blob1.isEqual(blob3)); // false
387
```
388
389
### Field Path Operations
390
391
Reference document fields, including nested fields and special field names.
392
393
```typescript { .api }
394
class FieldPath {
395
/**
396
* Special field path for document ID
397
* @returns FieldPath referencing the document ID
398
*/
399
static documentId(): FirebaseFirestoreTypes.FieldPath;
400
401
/**
402
* Create a field path from field names
403
* @param fieldNames - Sequence of field names for nested access
404
*/
405
constructor(...fieldNames: string[]);
406
407
/**
408
* Check if two field paths are equal
409
* @param other - Other FieldPath to compare
410
* @returns True if field paths are equal
411
*/
412
isEqual(other: FirebaseFirestoreTypes.FieldPath): boolean;
413
}
414
```
415
416
**Usage Examples:**
417
418
```typescript
419
import firestore from '@react-native-firebase/firestore';
420
421
// Create field paths for nested fields
422
const profileNamePath = new firestore.FieldPath('profile', 'displayName');
423
const settingsThemePath = new firestore.FieldPath('settings', 'ui', 'theme');
424
425
// Use in queries
426
const usersWithDisplayName = await firestore()
427
.collection('users')
428
.where(profileNamePath, '!=', null)
429
.get();
430
431
// Use in updates
432
await firestore().collection('users').doc('userId').update({
433
[profileNamePath]: 'John Doe',
434
[settingsThemePath]: 'dark'
435
});
436
437
// Alternative syntax for updates
438
await firestore().collection('users').doc('userId').update(
439
profileNamePath, 'Jane Doe',
440
settingsThemePath, 'light'
441
);
442
443
// Document ID field path (useful for queries)
444
const documentIdPath = firestore.FieldPath.documentId();
445
446
// Query using document ID
447
const specificUsers = await firestore()
448
.collection('users')
449
.where(documentIdPath, 'in', ['user1', 'user2', 'user3'])
450
.get();
451
452
// Order by document ID
453
const orderedByIdQuery = await firestore()
454
.collection('users')
455
.orderBy(documentIdPath)
456
.get();
457
458
// Complex nested field operations
459
const addressPath = new firestore.FieldPath('contact', 'address', 'street');
460
const phonePath = new firestore.FieldPath('contact', 'phone', 'primary');
461
462
await firestore().collection('users').doc('userId').update({
463
[addressPath]: '123 Main St',
464
[phonePath]: '+1-555-0123',
465
updatedAt: firestore.FieldValue.serverTimestamp()
466
});
467
```
468
469
### Type Validation and Conversion
470
471
```typescript { .api }
472
/**
473
* Check if a value is a Firestore Timestamp
474
*/
475
function isTimestamp(value: any): value is FirebaseFirestoreTypes.Timestamp;
476
477
/**
478
* Check if a value is a Firestore GeoPoint
479
*/
480
function isGeoPoint(value: any): value is FirebaseFirestoreTypes.GeoPoint;
481
482
/**
483
* Check if a value is a Firestore FieldValue
484
*/
485
function isFieldValue(value: any): value is FirebaseFirestoreTypes.FieldValue;
486
487
/**
488
* Check if a value is a Firestore Blob
489
*/
490
function isBlob(value: any): value is FirebaseFirestoreTypes.Blob;
491
492
/**
493
* Check if a value is a Firestore FieldPath
494
*/
495
function isFieldPath(value: any): value is FirebaseFirestoreTypes.FieldPath;
496
```
497
498
**Usage Examples:**
499
500
```typescript
501
import firestore from '@react-native-firebase/firestore';
502
503
// Type checking utility functions
504
function processDocumentData(data: any) {
505
Object.entries(data).forEach(([key, value]) => {
506
if (firestore.Timestamp.prototype.isPrototypeOf(value)) {
507
console.log(`${key} is a Timestamp:`, value.toDate());
508
} else if (firestore.GeoPoint.prototype.isPrototypeOf(value)) {
509
console.log(`${key} is a GeoPoint:`, value.latitude, value.longitude);
510
} else if (firestore.Blob.prototype.isPrototypeOf(value)) {
511
console.log(`${key} is a Blob with ${value.toUint8Array().length} bytes`);
512
} else {
513
console.log(`${key} is a regular value:`, value);
514
}
515
});
516
}
517
518
// Convert data for serialization
519
function serializeFirestoreData(data: any): any {
520
if (data === null || data === undefined) {
521
return data;
522
}
523
524
if (firestore.Timestamp.prototype.isPrototypeOf(data)) {
525
return { _type: 'timestamp', value: data.toMillis() };
526
}
527
528
if (firestore.GeoPoint.prototype.isPrototypeOf(data)) {
529
return { _type: 'geopoint', value: data.toJSON() };
530
}
531
532
if (firestore.Blob.prototype.isPrototypeOf(data)) {
533
return { _type: 'blob', value: data.toBase64() };
534
}
535
536
if (Array.isArray(data)) {
537
return data.map(serializeFirestoreData);
538
}
539
540
if (typeof data === 'object') {
541
const serialized: any = {};
542
Object.entries(data).forEach(([key, value]) => {
543
serialized[key] = serializeFirestoreData(value);
544
});
545
return serialized;
546
}
547
548
return data;
549
}
550
```
551
552
## Types
553
554
```typescript { .api }
555
/**
556
* Supported Firestore data types
557
*/
558
type DocumentFieldType =
559
| string
560
| number
561
| boolean
562
| { [key: string]: DocumentFieldType }
563
| DocumentFieldType[]
564
| null
565
| FirebaseFirestoreTypes.Timestamp
566
| FirebaseFirestoreTypes.GeoPoint
567
| FirebaseFirestoreTypes.Blob
568
| FirebaseFirestoreTypes.FieldPath
569
| FirebaseFirestoreTypes.FieldValue
570
| FirebaseFirestoreTypes.DocumentReference
571
| FirebaseFirestoreTypes.CollectionReference;
572
573
/**
574
* Document data structure
575
*/
576
interface DocumentData {
577
[field: string]: DocumentFieldType;
578
}
579
580
/**
581
* Snapshot options for data retrieval
582
*/
583
interface SnapshotOptions {
584
/**
585
* How to handle server timestamps that haven't been set yet
586
* - 'estimate': Use local estimate of server time
587
* - 'previous': Use previous field value
588
* - 'none': Return null for unresolved server timestamps
589
*/
590
serverTimestamps?: 'estimate' | 'previous' | 'none';
591
}
592
```