Notes

Cloud Firestore

Set a document

1
var data = {
2
name: 'Los Angeles',
3
state: 'CA',
4
country: 'USA',
5
};
6
7
// Add a new document in collection "cities" with ID 'LA'
8
var setDoc = db
9
.collection('cities')
10
.doc('LA')
11
.set(data);
Copied!

Data types

1
var data = {
2
stringExample: 'Hello, World!',
3
booleanExample: true,
4
numberExample: 3.14159265,
5
dateExample: new Date('December 10, 1815'),
6
arrayExample: [5, true, 'hello'],
7
nullExample: null,
8
objectExample: {
9
a: 5,
10
b: true,
11
},
12
};
13
14
var setDoc = db
15
.collection('data')
16
.doc('one')
17
.set(data);
Copied!

Add document with auto-generated ID

In a single-step with asynchronous access to the new ref
1
// Add a new document with a generated id.
2
var addDoc = db
3
.collection('cities')
4
.add({
5
name: 'Tokyo',
6
country: 'Japan',
7
})
8
.then(ref => {
9
console.log('Added document with ID: ', ref.id);
10
});
Copied!
In two steps with synchronous access to the new ref
1
// Add a new document with a generated id.
2
var newCityRef = db.collection('cities').doc();
3
4
console.log('newCityRef id:', newCityRef.id);
5
6
var setDoc = newCityRef
7
.set({
8
name: 'Tokyo',
9
country: 'Japan',
10
})
11
.then(ref => {
12
//...
13
});
Copied!

Update document

Note the optional merge: true option
1
var cityRef = db.collection('cities').doc('DC');
2
3
// Set the 'capital' field of the city
4
var updateSingle = cityRef.update({ capital: true }, { merge: true });
Copied!

Transactions

1
// Initialize document
2
var cityRef = db.collection('cities').doc('SF');
3
var setCity = cityRef.set({
4
name: 'San Francisco',
5
state: 'CA',
6
country: 'USA',
7
capital: false,
8
population: 860000,
9
});
10
11
var transaction = db
12
.runTransaction(t => {
13
return t.get(cityRef).then(doc => {
14
// Add one person to the city population
15
var newPopulation = doc.data().population + 1;
16
t.update(cityRef, { population: newPopulation });
17
});
18
})
19
.then(result => {
20
console.log('Transaction success!');
21
})
22
.catch(err => {
23
console.log('Transaction failure:', err);
24
});
Copied!

Batched writes

1
// Get a new write batch
2
var batch = db.batch();
3
4
// Set the value of 'NYC'
5
var nycRef = db.collection('cities').doc('NYC');
6
batch.set(nycRef, { name: 'New York City' });
7
8
// Update the population of 'SF'
9
var sfRef = db.collection('cities').doc('SF');
10
batch.update(sfRef, { population: 1000000 });
11
12
// Delete the city 'LA'
13
var laRef = db.collection('cities').doc('LA');
14
batch.delete(laRef);
15
16
// Commit the batch
17
return batch.commit().then(function() {
18
// ...
19
});
Copied!

Bulk delete

Max batch size is 500 records
1
function deleteCollection(db, collectionPath, batchSize) {
2
var collectionRef = db.collection(collectionPath);
3
var query = collectionRef.orderBy('__name__').limit(batchSize);
4
5
return new Promise((resolve, reject) => {
6
deleteQueryBatch(db, query, batchSize, resolve, reject);
7
});
8
}
9
10
function deleteQueryBatch(db, query, batchSize, resolve, reject) {
11
query
12
.get()
13
.then(snapshot => {
14
// When there are no documents left, we are done
15
if (snapshot.size == 0) {
16
return 0;
17
}
18
19
// Delete documents in a batch
20
var batch = db.batch();
21
snapshot.docs.forEach(doc => {
22
batch.delete(doc.ref);
23
});
24
25
return batch.commit().then(() => {
26
return snapshot.size;
27
});
28
})
29
.then(numDeleted => {
30
if (numDeleted === 0) {
31
resolve();
32
return;
33
}
34
35
// Recurse on the next process tick, to avoid
36
// exploding the stack.
37
process.nextTick(() => {
38
deleteQueryBatch(db, query, batchSize, resolve, reject);
39
});
40
})
41
.catch(reject);
42
}
Copied!

Get a document

1
var cityRef = db.collection('cities').doc('SF');
2
var getDoc = cityRef
3
.get()
4
.then(doc => {
5
if (!doc.exists) {
6
console.log('No such document!');
7
} else {
8
console.log('Document data:', doc.data());
9
}
10
})
11
.catch(err => {
12
console.log('Error getting document', err);
13
});
Copied!

Get an entire collection

1
var citiesRef = db.collection('cities');
2
var allCities = citiesRef
3
.get()
4
.then(snapshot => {
5
snapshot.forEach(doc => {
6
console.log(doc.id, '=>', doc.data());
7
});
8
})
9
.catch(err => {
10
console.log('Error getting documents', err);
11
});
Copied!

Get with a where clause

1
var citiesRef = db.collection('cities');
2
var query = citiesRef
3
.where('capital', '==', true)
4
.get()
5
.then(snapshot => {
6
snapshot.forEach(doc => {
7
console.log(doc.id, '=>', doc.data());
8
});
9
})
10
.catch(err => {
11
console.log('Error getting documents', err);
12
});
Copied!

List subcollections

1
var sfRef = db.collection('cities').doc('SF');
2
sfRef.getCollections().then(collections => {
3
collections.forEach(collection => {
4
console.log('Found subcollection with id:', collection.id);
5
});
6
});
Copied!

Listen for document changes

1
var doc = db.collection('cities').doc('SF');
2
3
var observer = doc.onSnapshot(
4
docSnapshot => {
5
console.log(`Received doc snapshot: ${docSnapshot}`);
6
// ...
7
},
8
err => {
9
console.log(`Encountered error: ${err}`);
10
}
11
);
Copied!

Listen for collection changes

1
var query = db.collection('cities').where('state', '==', 'CA');
2
3
var observer = query.onSnapshot(
4
querySnapshot => {
5
console.log(`Received query snapshot of size ${querySnapshot.size}`);
6
// ...
7
},
8
err => {
9
console.log(`Encountered error: ${err}`);
10
}
11
);
Copied!

Stop listening

1
var unsub = db.collection('cities').onSnapshot(() => {});
2
3
// ...
4
5
// Stop listening for changes
6
unsub();
Copied!

Compound queries

Valid queries
1
citiesRef.where('state', '==', 'CO').where('name', '==', 'Denver');
2
3
citiesRef.where('state', '==', 'CA').where('population', '<', 1000000);
4
5
citiesRef.where('state', '>=', 'CA').where('state', '<=', 'IN');
6
7
citiesRef.where('state', '==', 'CA').where('population', '>', 1000000);
Copied!
!!! INVALID QUERY AHEAD !!!
1
// Invalid query. Will throw an error.
2
citiesRef.where('state', '>=', 'CA').where('population', '>', 1000000);
Copied!

Order and limit

Valid order/limit combinations
1
var firstThree = citiesRef.orderBy('name').limit(3);
2
3
var lastThree = citiesRef.orderBy('name', 'desc').limit(3);
4
5
var byStateByPop = citiesRef.orderBy('state').orderBy('population', 'desc');
6
7
var biggest = citiesRef
8
.where('population', '>', 2500000)
9
.orderBy('population')
10
.limit(2);
11
12
var allBigCities = citiesRef.where('population', '>', 2500000).orderBy('population');
Copied!
!!! INVALID QUERY AHEAD !!!
1
// Invalid query. Will throw an error.
2
citiesRef.where('population', '>', 2500000).orderBy('country');
Copied!

Pagination: single-cursor

Valid pagination
1
var startAt = db
2
.collection('cities')
3
.orderBy('population')
4
.startAt(1000000);
5
6
var startAfter = db
7
.collection('cities')
8
.orderBy('population')
9
.startAfter(1000000);
10
11
var endAt = db
12
.collection('cities')
13
.orderBy('population')
14
.endAt(1000000);
15
16
var endBefore = db
17
.collection('cities')
18
.orderBy('population')
19
.endBefore(1000000);
Copied!

Pagination: multiple-cursors

1
// Will return all Springfields
2
var startAtName = db
3
.collection('cities')
4
.orderBy('name')
5
.orderBy('state')
6
.startAt('Springfield');
7
8
// Will return "Springfield, Missouri" and "Springfield, Wisconsin"
9
var startAtNameAndState = db
10
.collection('cities')
11
.orderBy('name')
12
.orderBy('state')
13
.startAt('Springfield', 'Missouri');
Copied!
Last modified 3yr ago