Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Firestore: QoL improvements for converters #5268

Merged
merged 27 commits into from
Aug 18, 2021
Merged

Firestore: QoL improvements for converters #5268

merged 27 commits into from
Aug 18, 2021

Conversation

thebrianchen
Copy link

@thebrianchen thebrianchen commented Aug 10, 2021

Fixes #4277.

Changes implemented:

  • Support for FieldValues when using a converter
  • Support for nested Partial fields when using a converter.
  • Support for UpdateData with converter.

@changeset-bot
Copy link

changeset-bot bot commented Aug 10, 2021

🦋 Changeset detected

Latest commit: 635c9e3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
firebase Major
@firebase/firestore Major
@firebase/rules-unit-testing Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@github-actions
Copy link
Contributor

github-actions bot commented Aug 10, 2021

Changeset File Check ✅

  • No modified packages are missing from the changeset file.
  • No changeset formatting errors detected.

Copy link
Contributor

@schmidt-sebastian schmidt-sebastian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Roughly LGTM :)

@@ -48,6 +49,21 @@ export interface DocumentData {
[field: string]: any;
}

type Primitive = string | number | boolean | bigint | undefined | null;
// eslint-disable-next-line @typescript-eslint/ban-types
type Builtin = Primitive | Function;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we use Function?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used it when I had special FieldValue return types. Removed it.

packages/firestore/src/lite/reference.ts Outdated Show resolved Hide resolved
packages/firestore/src/lite/reference.ts Outdated Show resolved Hide resolved
@google-oss-bot
Copy link
Contributor

google-oss-bot commented Aug 12, 2021

Binary Size Report

Affected SDKs

  • @firebase/firestore

    Type Base (cca8cdf) Head (5301fc7) Diff
    browser 285 kB 285 kB -136 B (-0.0%)
    esm2017 227 kB 227 kB +28 B (+0.0%)
    main 531 kB 531 kB +54 B (+0.0%)
    module 285 kB 285 kB -136 B (-0.0%)
    react-native 227 kB 227 kB +28 B (+0.0%)
  • @firebase/firestore-compat

    Type Base (cca8cdf) Head (5301fc7) Diff
    browser 29.0 kB 29.0 kB +54 B (+0.2%)
    main 38.1 kB 38.2 kB +64 B (+0.2%)
    module 29.0 kB 29.0 kB +54 B (+0.2%)
    react-native 28.7 kB 28.7 kB +54 B (+0.2%)
  • @firebase/firestore/bundle

    Type Base (cca8cdf) Head (5301fc7) Diff
    browser 291 kB 291 kB +28 B (+0.0%)
    esm2017 177 kB 177 kB +28 B (+0.0%)
    main 527 kB 528 kB +54 B (+0.0%)
    module 291 kB 291 kB +28 B (+0.0%)
    react-native 177 kB 177 kB +28 B (+0.0%)
  • @firebase/firestore/memory

    Type Base (cca8cdf) Head (5301fc7) Diff
    browser 217 kB 217 kB +116 B (+0.1%)
    esm2017 173 kB 173 kB +28 B (+0.0%)
    main 325 kB 325 kB +54 B (+0.0%)
    module 217 kB 217 kB +116 B (+0.1%)
    react-native 173 kB 173 kB +28 B (+0.0%)
  • @firebase/firestore/memory-bundle

    Type Base (cca8cdf) Head (5301fc7) Diff
    browser 225 kB 225 kB +28 B (+0.0%)
    esm2017 177 kB 177 kB +28 B (+0.0%)
    main 322 kB 322 kB +54 B (+0.0%)
    module 225 kB 225 kB +28 B (+0.0%)
    react-native 177 kB 177 kB +28 B (+0.0%)
  • firebase

    Type Base (cca8cdf) Head (5301fc7) Diff
    firebase-firestore.js 337 kB 337 kB +28 B (+0.0%)
    firebase-firestore.memory.js 271 kB 271 kB +28 B (+0.0%)
    firebase.js 896 kB 896 kB +28 B (+0.0%)

Test Logs

@google-oss-bot
Copy link
Contributor

google-oss-bot commented Aug 12, 2021

Size Analysis Report

Affected Products

No changes between base commit (cca8cdf) and head commit (5301fc7).

Copy link
Contributor

@schmidt-sebastian schmidt-sebastian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is great. Some cleanup suggestions, most of which you will probably push back on :)

toFirestore(modelObject: T): DocumentData;
toFirestore(modelObject: Partial<T>, options: SetOptions): DocumentData;
toFirestore(modelObject: WithFieldValue<T>): DocumentData;
toFirestore(modelObject: NestedPartial<T>, options: SetOptions): DocumentData;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we were going to align those two names. Have you thought of a naming pattern that would achieve that?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to PartialWithFieldValue.

packages/firebase/index.d.ts Show resolved Hide resolved
@@ -22,7 +22,7 @@ import { _FirebaseNamespace } from '@firebase/app-types/private';
import { Component, ComponentType } from '@firebase/component';

import {
FirebaseFirestore,
Firestore as FirebaseFirestore,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intentional?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Not sure how this worked in the past, since FirebaseFirestore isn't exported by ../exp/index.

NestedUpdateFields,
AddPrefixToKeys,
NestedPartial,
UnionToIntersection,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional: I think it would be cleaner if these were exports from a dedicated module, which would make it easier to understand that SetOptions and Primitive are completely unrelated.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you saying to move the helper types into a separate exp/helper.ts file, or for lite as well?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like lite/types.ts that you can refer to from exp/ and lite/

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved into lite/types

@@ -452,9 +453,9 @@ export class Transaction implements PublicTransaction, Compat<ExpTransaction> {
const ref = castReference(documentRef);
if (options) {
validateSetOptions('Transaction.set', options);
this._delegate.set(ref, data, options);
this._delegate.set(ref, data as NestedPartial<T>, options);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these needed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, since the method parameter types are T | Partial<T>, we have to cast.

@@ -73,8 +73,8 @@ const RESERVED_FIELD_REGEX = /^__.*__$/;
* lite, firestore-exp and classic SDK.
*/
export interface UntypedFirestoreDataConverter<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also update the docs for FirestoreDataConverter to explain what this new input type is.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added for UntypedFirestoreDataConverter and FirestoreDataConverter.

packages/firestore/test/lite/integration.test.ts Outdated Show resolved Hide resolved
packages/firestore/test/lite/integration.test.ts Outdated Show resolved Hide resolved
packages/firestore/test/lite/integration.test.ts Outdated Show resolved Hide resolved
const ref = doc(collection(db, 'testobj')).withConverter(
testConverter
);
await setBaseDoc(ref);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is also withTestDocAndInitialData that should give you an existing doc.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@thebrianchen thebrianchen changed the title Firestore: Prototyping for TS updates Firestore: QoL improvements for converters Aug 18, 2021
Copy link
Contributor

@schmidt-sebastian schmidt-sebastian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

.changeset/dirty-pandas-pay.md Outdated Show resolved Hide resolved
packages/firestore/src/exp/snapshot.ts Show resolved Hide resolved
packages/firestore/src/exp/snapshot.ts Outdated Show resolved Hide resolved
packages/firestore/src/lite/reference.ts Outdated Show resolved Hide resolved
packages/firestore/src/lite/snapshot.ts Show resolved Hide resolved
packages/firestore/src/lite/snapshot.ts Outdated Show resolved Hide resolved
@svailla4
Copy link

svailla4 commented Aug 25, 2021

UpdateData is very nice, but is there a way to make dot notation work with optional fields? @thebrianchen
Example: link

@thebrianchen
Copy link
Author

@svailla4 Thanks for catching this! Will look into this some more.

@ishowta
Copy link

ishowta commented Aug 28, 2021

This allows for dot notation in the middle of the object, but this probably won't work. link

type Schema = {
  foo: {
    bar: {
      baz: number
    }
  }
}

const updateData: UpdateData<Schema> = {
  foo: {
    "bar.baz": 3
  }
}

@ishowta
Copy link

ishowta commented Aug 28, 2021

I get an error when using this with Record in Typescript 4.4. link
This is probably due to the fact that the records are somehow appearing at the top level (regardless of the Typescript version).

type Schema = {
  foo: {
    bar: Record<string, string>
  }
}

const updateData: UpdateData<Schema> = {
  foo:{
    bar: {
      baz: 'hello'
    }
  }
}

2021-08-29_041708
2021-08-29_041719

@firebase firebase locked and limited conversation to collaborators Sep 18, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FR: improve typing on CRUD methods (again)
8 participants