Description
Is your feature request related to a problem?
I followed the Readme for getting some user data like this:
const firestore = FirestoreApp.getFirestore(email, key, projectId);
const userSnap = firestore.query("users").Where("email", "==", userEmail).Limit(1).Offset(0).Execute()?.[0];
const userDoc = userSnap?.["fields"] ?? {};
userDoc is rather verbose, and requires calls like:
userDoc["uid"].stringValue
I see in the library code there is a Document.ts class with a perfect unwrap static method to turn userSnap into a simple JSON object.
Describe the solution you'd like
Can you explain how to access this Document.unwrap method in an Apps Script?
I tried "const userData = new FirestoreApp.Document(userSnap);" among other things and just couldn't figure it out.
It would be a good idea to add this to the documentation, as it would save others a tremendous amount of time debugging and reinventing the wheel.
Describe alternatives you've considered
I got unwrapping working by copying the following methods into Code.gs in Apps Script:
function unwrapObject(obj) {
return Object.entries(obj.fields || {}).reduce(
(o, [key, val]) => {
o[key] = unwrapValue(val);
return o;
},
{}
);
}
function unwrapValue(obj) {
let [type, val] = Object.entries(obj)[0];
switch (type) {
case 'referenceValue':
case 'bytesValue':
case 'stringValue':
case 'booleanValue':
case 'geoPointValue':
return val;
case 'doubleValue':
return parseFloat(val);
case 'integerValue':
return parseInt(val);
case 'mapValue':
return unwrapObject(val);
case 'arrayValue':
console.log("type === arrayValue:", val);
return unwrapArray(val.values);
case 'timestampValue':
return this.unwrapDate(val);
case 'nullValue':
default:
return null;
}
}
function unwrapArray(wrappedArray) {
console.log("unwrapArray", wrappedArray);
return wrappedArray?.map(value => unwrapValue(value)) ?? [];
}
function unwrapDate(wrappedDate) {
// Trim out extra microsecond precision
return new Date(wrappedDate.replace(/(\.\d{3})\d+/, '$1'));
}
Then you can call
const userData = unwrapObject(userSnap);
... to get JSON like usually returned from firebase npm for instance.
This solution seems not ideal as it duplicates code with the library. Let me know if there's a better way.
btw, thank you for this library :)