Skip to content

Add examples of unwrapping firebase data #171

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions