Search Lessons, Code Snippets, and Videos
search by algolia
X
#native_cta# #native_desc# Sponsored by #native_company#

How to Format Document Data for the Firestore REST API

written by Jeff Delaney
full courses for pro members

Formatting data for the Firestore REST API is a bit of a pain. A document’s data is not true JSON, so we need to explicitly tell the database the type of every value. This is one of those situations where LoDash is extremely helpful. Not only will we use it to map object values, but we can also use it to check datatypes with isString, isArray, etc.

Let’s imagine we have a plain JS object that looks like:

data = {
name: 'Jeff'
time: new Date()
stuff: [ 23, true ]
}

The snippet below will convert it to a following Firestore-compliant format that looks like this:.

data = {
fields: {
name: { "stringValue": "Jeff" },
time: { "timestampValue": new Date() },
stuff: {
"arrayValue": {
"values": {
"numberValue": 23,
"booleanValue": true
}
}
}
}
}

A Recursive Function to Map Firestore REST Requests

We need a way to format every property as a Firestore Value, and that also includes values nested in objects and array. It’s a perfect situation for a recursive function when we hit an ArrayValue or MapValue. This code will work for all JS primitives, but not any of the special Firestore types like GeoPoint or DocumentReference.

// Thanks LoDash!
import {
mapValues,
isString,
isNumber,
isArray,
isNull,
isBoolean,
isObject,
isDate
} from 'lodash';

// Pass a plain JS Object
function firestoreMap(data) {
return mapValues(data, (v) => {
if (isString(v))
return { "stringValue": v }

if (isNumber(v))
return { "integerValue": v }

if (isNull(v))
return { "nullValue": v }

if (isDate(v))
return { "timestampValue": v }

if (isBoolean(v))
return { "booleanValue": v }

if (isObject(v))
return { "mapValue": { "fields": firestoreMap(v) } }

if (isArray(v))
return { "arrayValue": { "values": firestoreMap(v) } }

return { "stringValue": "UNABLE TO MAP VALUE" }
});
}