When fetching data in a firebase cloud function from firestore we get is not assignable errors when using a converter

Viewed 590

I am writing a cloud function that needs to retrieve a document from firestore using get(). I then need to use this data, so I am trying to use a converter so I can use the object later on down the line. The converter uses FamilyRequest to specify fields. Here is the relevant code:

import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
import * as firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';

admin.initializeApp();

const db = admin.firestore();
const settings = {timestampsInSnapshots: true};
db.settings(settings);

class FamilyRequest {
  recipient;
  sender;
  familyId;
  role;
  senderIsModGuard;

  constructor (recipient: string, sender: string, familyId: string, role: string, senderIsModGuard: boolean) {
      this.recipient = recipient;
      this.sender = sender;
      this.familyId = familyId;
      this.role = role;
      this.senderIsModGuard = senderIsModGuard;
  }
  toString() {
      return this.recipient + ', ' + this.sender + ', ' + this.familyId + ', ' + this.role + ', ' + this.senderIsModGuard;
  }
}

const familyRequestConverter = {
  toFirestore(famrequest: FamilyRequest): firebase.firestore.DocumentData {
    return {
      recipient: famrequest.recipient,
      sender: famrequest.sender,
      familyId: famrequest.familyId,
      role: famrequest.role,
      senderIsModGuard: famrequest.senderIsModGuard
      };
  },
  fromFirestore(
    snapshot: firebase.firestore.QueryDocumentSnapshot,
    options: firebase.firestore.SnapshotOptions
  ): FamilyRequest {
    const data = snapshot.data(options)!;
    return new FamilyRequest(data.recipient, data.sender, data.familyId, data.role, data.senderIsModGuard);
  }
};


export const acceptFamilyRequestFromFamilyModerator = functions.https.onCall(
  async (data, context) => {

     // Message text passed from the client.
     if (data && context && context.auth && context.auth.uid) {
      const groupId = data.text.groupId;
      // Authentication info is automatically added to the request.
      const uid = context.auth.uid;
      const requid = data.text.uid;
      
      const famrequestrecipient = data.text.famrequestrecipient;
      const famrequestsender = data.text.famrequestsender; //this is the original sender of the famrequest

      //Do sender/recipient checks here

      const ref = await db.collection("famrequests")
        .doc(uid)
        .collection('myfamrequests')
        .doc(famrequestrecipient)
        .withConverter(familyRequestConverter)
        .get()
          .then(doc => { //This is simplified for now
            if (doc.exists) {
              return doc;
            } else {
              return null;
            }
          });

     }

  });

When entering this code into the IDE, the following errors come up:

No overload matches this call. Overload 1 of 2, '(converter: null): DocumentReference', gave the following error. Argument of type '{ toFirestore(famrequest: FamilyRequest): DocumentData; fromFirestore(snapshot: QueryDocumentSnapshot, options: SnapshotOptions): FamilyRequest; }' is not assignable to parameter of type 'null'. Overload 2 of 2, '(converter: FirestoreDataConverter): DocumentReference', gave the following error. Argument of type '{ toFirestore(famrequest: FamilyRequest): DocumentData; fromFirestore(snapshot: QueryDocumentSnapshot, options: SnapshotOptions): FamilyRequest; }' is not assignable to parameter of type 'FirestoreDataConverter'. Types of property 'fromFirestore' are incompatible. Type '(snapshot: QueryDocumentSnapshot, options: SnapshotOptions) => FamilyRequest' is not assignable to type '(snapshot: QueryDocumentSnapshot) => FamilyRequest'.ts(2769) const familyRequestConverter: { toFirestore(famrequest: FamilyRequest): firebase.firestore.DocumentData; fromFirestore(snapshot: firebase.firestore.QueryDocumentSnapshot, options: firebase.firestore.SnapshotOptions): FamilyRequest; }

I am not entirely sure what I am doing wrong as I am following the example code for converters here: https://firebase.google.com/docs/firestore/query-data/get-data#web-version-8_3 very closely.

Any help is much appreciated.

2 Answers

I made the following change to familyRequestConverter that worked:

const familyRequestConverter = {
  toFirestore: function(famrequest: FamilyRequest): firebase.firestore.DocumentData {
    return {
      recipient: famrequest.recipient,
      sender: famrequest.sender,
      familyId: famrequest.familyId,
      role: famrequest.role,
      senderIsModGuard: famrequest.senderIsModGuard,
      };
  },
  fromFirestore: function(
    snapshot: firebase.firestore.DocumentData
  ) {
    const data = snapshot.data()!;
    return new FamilyRequest(data.recipient, data.sender, data.familyId, data.role, data.senderIsModGuard);
  }
};

This overloading error can be cause if you are missing either toFirestore or fromFirestore functions in the converter object which is passed to withConverter function.

Related