云函数(TypeScript)-如何使用自定义模型而不是嵌套的映射/字典

云函数(TypeScript)-如何使用自定义模型而不是嵌套的映射/字典,typescript,firebase,google-cloud-firestore,google-cloud-functions,Typescript,Firebase,Google Cloud Firestore,Google Cloud Functions,我在我的云函数中为用户和帖子定制了如下模型(models.ts): 我不想处理firestore DocumentSnapshot中的map/dictionary对象,而是想填充这些模型。通过这种方式,我可以以更无错误的方式操作字段 我找到了解决这个问题的方法。Firestore文档中有一个示例,其中显示了不同的实现。为了方便起见,我将代码复制粘贴到了下面的链接中: class Post { constructor(readonly title: string, readonly autho

我在我的云函数中为用户和帖子定制了如下模型(models.ts):

我不想处理firestore DocumentSnapshot中的map/dictionary对象,而是想填充这些模型。通过这种方式,我可以以更无错误的方式操作字段

我找到了解决这个问题的方法。Firestore文档中有一个示例,其中显示了不同的实现。为了方便起见,我将代码复制粘贴到了下面的链接中:

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
}


这两种方法都会在我的
云函数中创建错误,该函数是用TypeScript编写的。我的问题是
FirestoreDataConverter
最好的方法是什么?有哪些选择?是否有人可以发布一种正确的方式来建模用于云功能的userpost关系?(请记住,这两个模型都将另一个模型作为属性,如果服务器上的地图具有嵌套地图,会发生什么情况?

有两个很好的视频和文档,介绍了构建数据的方法,包括maps@Tedskovsky谢谢你的链接,但我不是在说构建数据库。我的数据库已经结构化了。我只想通过使用自定义对象模型而不是操作贴图,使我的云函数typescript代码更结构化。也许我的问题不清楚?请随意编辑。没问题-我想看视频4可能会有所帮助,在视频4中,Todd讨论了为什么使用内置数据结构比使用自己的数据结构更有效。不是答案,但看看阅读是如何工作的很有趣
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
}
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"));