如何将来自 Firebase 的查询快照转换为不同的对象?

Posted

技术标签:

【中文标题】如何将来自 Firebase 的查询快照转换为不同的对象?【英文标题】:How to convert Query Snapshot from Firebase into a different object? 【发布时间】:2020-08-20 15:16:02 【问题描述】:

在下面的方法中,我从 Firebase 集合中检索文档。

我已经成功记录了调用getUserByUserId() 时需要返回的值,但我需要将它们作为User 对象返回:

getUserByUserId(userId: string) 
    return of(firebase.firestore().collection("users").where("userId", "==", userId)
      .get().then(querySnapshot => 
        querySnapshot.forEach(doc => 
          console.log("User ID", "=>", doc.data().userId);
          console.log("Username", "=>", doc.data().userName);
          console.log("Mechanic", "=>", doc.data().isMechanic);
          console.log("Location", "=>", doc.data().location);
        )
      ).catch(err => 
        console.log(err);
      ));
  

这是数据需要遵循的User 结构:

import  PlaceLocation  from './location.model';

export class User 
    constructor(
        public id: string,
        public name: string,
        public isMechanic: boolean,
        public email: string,
        public location: PlaceLocation
    )  

谁能告诉我如何使用这些数据创建一个User 对象并将其作为getUserByUserId() 的响应返回?

【问题讨论】:

你在管道map()里面做什么? map 用于操作返回的 Observable 并且必须返回一个值。出于记录目的,您可以使用tap 或者,返回您在地图中收到的对象 我想要使用getUserByUserId() 的目的是从firebase 返回整个User 对象,以便我可以将其分配给this.user 去掉 map() 试试 嗨@AshishRanjan 我已经更新了我上面的问题,你能看看吗? 【参考方案1】:

使用@angular/fire,您可以按照以下方式进行操作

constructor(private firestore: AngularFirestore) 


getUserByUserId(userId: string) 

    return this.firestore
      .collection("users", ref => ref.where("userId", "==", userId))
      .get()
      .pipe(
        filter(ref => !ref.empty),
        map(ref => ref.docs[0].data() as User),
        map(data => new User(data, data.location))
      )


更新

如果你需要对象实例,你应该有像这样的额外构造函数 about object assign

export class User 
    constructor(
        public id: string,
        public name: string,
        public contactNumber: number,
        public isMechanic: boolean,
        public email: string,
        public password: string,
        public address: string,
        public imageUrl: string,
        public location: PlaceLocation
    )  

    public constructor(
      init?: Partial<User>,
      initLocation?: Partial<PlaceLocation>) 

        Object.assign(this, init);
        if(initLocation) 
          this.location = new PlaceLocation(initLocation);
        
    


export class PlaceLocation 
    constructor()  

    public constructor(init?: Partial<PlaceLocation>) 
        Object.assign(this, init);
    

因为您将数据作为没有类型的对象读取,所以您只能显式创建一个新的用户对象并使用来自对象的数据为其分配属性

getUserByUserId(userId: string) 

    return this.firestore
      .collection("users", ref => ref.where("userId", "==", userId))
      .get()
      .pipe(
        filter(ref => !ref.empty),
        map(ref => ref.docs[0].data() as User),
        map(data => new User(data, data.location))
      )


【讨论】:

感谢您的回答。我已经用更多代码更新了我的问题。你能看一下吗? 我希望得到一个答案,告诉我如何将map 的结果getUserByUserId 传递给我的对象,这可能吗? @user9847788 函数 getUserByUserId 中的最后一个地图做映射 - map(data => new User(data, data.location))

以上是关于如何将来自 Firebase 的查询快照转换为不同的对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 firbease 的 DataSnapshot 转换为 json 文件或如何将 firebase 数据库检索为 json 文件

查询未知父firebase的子快照

将 Firebase 快照投射到 Swift 3 对象

如何在firebase-flutter中为快照数据指定字段[重复]

Swift Firebase 快照查询缺少孩子

Firebase 快照未正确解析数据