Облачные функции (TypeScript) - Как использовать пользовательские модели вместо вложенных карт / словарей - PullRequest
1 голос
/ 07 марта 2020

Я сделал пользовательские модели для пользователей и сообщений в моих облачных функциях следующим образом (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?
    }
}

Вместо того, чтобы иметь дело с объектами карты / словаря из firestore documentSnapshots, я хочу заполнить их Модели. Таким образом, я могу манипулировать полями более безошибочным способом.

Я нашел около FirestoreDataConverter , который предположительно помогает решить эту проблему. В документации Firestore есть учебник Custom Objects , в котором показана другая реализация. Я скопировал вставленные коды в ссылках ниже для простоты:

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"));

Оба эти создают ошибки в моем коде Cloud Functions, который написан на TypeScript. Мой вопрос FirestoreDataConverter лучший способ для этого? Какие есть варианты? Может ли кто-нибудь опубликовать правильный способ моделирования отношений между пользователями <-> и использовать в облачных функциях? (учитывая, что обе модели имеют другую модель как свойства, а также что произойдет, если карты с сервера имеют вложенные карты?)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...