Skip to content

[Firestore] Typescript interface missing in the admin SDK for FirestoreDataConverter #1074

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

Closed
sagar7993 opened this issue Oct 26, 2020 · 5 comments · Fixed by #1080
Closed
Assignees

Comments

@sagar7993
Copy link

[READ] Step 1: Are you in the right place?

Cloud Firestore support is provided by the @google-cloud/firestore library. Therefore the easiest and most efficient way to get Firestore issues resolved is by directly reporting them at the nodejs-firestore GitHub repo.

If you still think the problem is related to the code in this repository, then read on.

  • For issues or feature requests related to the code in this repository
    file a Github issue.
  • For general technical questions, post a question on StackOverflow
    with the firebase tag.
  • For general Firebase discussion, use the firebase-talk
    google group.
  • For help troubleshooting your application that does not fall under one
    of the above categories, reach out to the personalized
    Firebase support channel.

[REQUIRED] Step 2: Describe your environment

  • Operating System version: Mac OS X
  • Firebase SDK version: 7.24.0
  • Firebase Product: Firestore
  • Node.js version: 12.9.0
  • NPM version: 6.14.8

[REQUIRED] Step 3: Describe the problem

Steps to reproduce:

Typescript interface missing in the admin SDK for FirestoreDataConveerter. As a result, I'm unable to use the withConverter method safely in my firestore queries.

Relevant Code:

firestore.collection(FireStoreCollections.Invoices).doc(invoice.id).withConverter().get();
// This does not work in typescript

Possible solution

I want to implement a data converter in typescript, somewhat like this

export const UserConverter: admin.firestore.FirestoreDataConverter<UserData> = {
	toFirestore(data: UserData): admin.firestore.DocumentData {
		const convertedDocumentData: admin.firestore.DocumentData = { ...data };
		return convertedDocumentData as UserData;
	},
	fromFirestore(
		snapshot: admin.firestore.QueryDocumentSnapshot,
		options: admin.firestore.SnapshotOptions
	): UserData {
		return snapshot.data(options) as UserData;
	}
};

To achieve this, we can export in interface from within the admin SDK's types, somewhat like this

namespace admin {

  /**
   * An options object that configures the behavior of `set()` calls in
   * {@link firebase.firestore.DocumentReference.set DocumentReference}, {@link
   * firebase.firestore.WriteBatch.set WriteBatch} and {@link
   * firebase.firestore.Transaction.set Transaction}. These calls can be
   * configured to perform granular merges instead of overwriting the target
   * documents in their entirety by providing a `SetOptions` with `merge: true`.
   */
  export interface SetOptions {
    /**
     * Changes the behavior of a set() call to only replace the values specified
     * in its data argument. Fields omitted from the set() call remain
     * untouched.
     */
    readonly merge?: boolean;

    /**
     * Changes the behavior of set() calls to only replace the specified field
     * paths. Any field path that is not specified is ignored and remains
     * untouched.
     */
    readonly mergeFields?: (string | FieldPath)[];
  }

  /**
   * Converter used by `withConverter()` to transform user objects of type T
   * into Firestore data.
   *
   * Using the converter allows you to specify generic type arguments when
   * storing and retrieving objects from Firestore.
   *
   * @example
   * ```typescript
   * class Post {
   *   constructor(readonly title: string, readonly author: string) {}
   *
   *   toString(): string {
   *     return this.title + ', by ' + this.author;
   *   }
   * }
   *
   * const postConverter = {
   *   toFirestore(post: Post): firebase.firestore.DocumentData {
   *     return {title: post.title, author: post.author};
   *   },
   *   fromFirestore(
   *     snapshot: firebase.firestore.QueryDocumentSnapshot,
   *     options: firebase.firestore.SnapshotOptions
   *   ): Post {
   *     const data = snapshot.data(options)!;
   *     return new Post(data.title, data.author);
   *   }
   * };
   *
   * const postSnap = await firebase.firestore()
   *   .collection('posts')
   *   .withConverter(postConverter)
   *   .doc().get();
   * const post = postSnap.data();
   * if (post !== undefined) {
   *   post.title; // string
   *   post.toString(); // Should be defined
   *   post.someNonExistentProperty; // TS error
   * }
   * ```
   */
  export interface FirestoreDataConverter<T> {
    /**
     * Called by the Firestore SDK to convert a custom model object of type T
     * into a plain Javascript object (suitable for writing directly to the
     * Firestore database). To use `set()` with `merge` and `mergeFields`,
     * `toFirestore()` must be defined with `Partial<T>`.
     */
    toFirestore(modelObject: T): DocumentData;
    toFirestore(modelObject: Partial<T>, options: SetOptions): DocumentData;

    /**
     * Called by the Firestore SDK to convert Firestore data into an object of
     * type T. You can access your data by calling: `snapshot.data(options)`.
     *
     * @param snapshot A QueryDocumentSnapshot containing your data and metadata.
     * @param options The SnapshotOptions from the initial call to `data()`.
     */
    fromFirestore(snapshot: QueryDocumentSnapshot, options: SnapshotOptions): T;
  }

}
@google-oss-bot
Copy link

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

@sagar7993 sagar7993 changed the title [Firestore] Typescript interface missing in the admin SDK for FirestoreDataConveerter [Firestore] Typescript interface missing in the admin SDK for FirestoreDataConverter Oct 26, 2020
@schmidt-sebastian
Copy link
Contributor

Thanks for filing this! This needs to be addressed in the Firebase Admin SDK, so @hiranya911 is a better owner.

@hiranya911
Copy link
Contributor

This is similar to #1064

@schmidt-sebastian what other new types should be re-exported from firebase-admin?

@schmidt-sebastian
Copy link
Contributor

This might be the list:

BulkWriter
CollectionGroup
QueryPartition
GrpcStatus
UpdateData (type only)
Settings (type only)
BulkWriterOptions (type only)
Preconidtion (type only) 
ReadOptions (type only)
DocumentChangeType (type only)

@sagar7993
Copy link
Author

@schmidt-sebastian @hiranya911 Thank you guys for the swift response 👏 Any idea when this can be released?

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

Successfully merging a pull request may close this issue.

4 participants