Búsqueda de sitios web

firebase - Cloud Functions(TypeScript) - Cómo usar modelos personalizados en lugar de mapas/diccionarios anidados


Hice modelos personalizados para usuarios y publicaciones en mis funciones en la nube de la siguiente manera (models.ts):

export class UserModel {
    picture?: string;
    fullName: string;
    totalPostsCount?: number;
    recentPosts?: PostModel[];

    constructor(userMap: any) {   //the documentations usually had specific properties for the constructor instead of a map/dictionary. I thought this would be better. Am I wrong?
        this.fullName = userMap.fullName;
        this.picture = userMap.picture;
        this.totalPostsCount = userMap.totalPostsCount;
        this.recentPosts = userMap.recentPosts;     //since this is another Custom Model, do we need to convert userMap.recentPosts dictionary array to PostModel[] here?
    }
}

export class PostModel {
    title: string;
    postDate: admin.firestore.Timestamp;   //is this the right type for a date object in cloud functions? there is also a FirebaseFirestore.Timestamp
    creator_user: UserModel;

    constructor(postMap: any) {
        this.title = postMap.title;
        this.creator_user = postMap.creator_user;   //since this is another Custom Model, do we need to convert postMap.creator_user dictionary to UserModel here?
    }
}

En lugar de trabajar con objetos mapa/diccionario de los documentSnapshots de Firestore, quiero llenar estos Modelos. De esta manera puedo manipular los campos de una forma más libre de errores.

Encontré información sobre FirestoreDataConverter que supuestamente ayuda con este problema. Hay un tutorial de Objetos Personalizados en la documentación de Firestore que muestra una implementación diferente. Copié y pegué los códigos en los enlaces a continuación para mayor facilidad:

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
}

Y;

class City {
    constructor (name, state, country ) {
        this.name = name;
        this.state = state;
        this.country = country;
    }
    toString() {
        return this.name + ', ' + this.state + ', ' + this.country;
    }
}

    // Firestore data converter
  cityConverter = {
      toFirestore: function(city) {
          return {
              name: city.name,
              state: city.state,
              country: city.country
              }
      },
      fromFirestore: function(snapshot, options){
          const data = snapshot.data(options);
          return new City(data.name, data.state, data.country)
      }
  }

 // Set with cityConverter
db.collection("cities").doc("LA")
  .withConverter(cityConverter)
  .set(new City("Los Angeles", "CA", "USA"));

Ambos crean errores en mi código de Cloud Functions que está escrito en TypeScript. Mi pregunta es, ¿FirestoreDataConverter es la mejor manera para esto? ¿Cuáles son las opciones? ¿Alguien podría publicar la manera correcta de modelar una relación usuario<->publicación para usar en las funciones de la nube? (teniendo en cuenta que ambos modelos tienen al otro modelo como propiedades y también qué pasaría si los mapas del servidor tienen mapas anidados)

Artículos relacionados