Skip to content

Add examples of unwrapping firebase data #171

Open
@tomchify

Description

@tomchify

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 :)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions