【问题标题】:Firestore where function not working as expected in Ionic / Angular appFirestore 在 Ionic / Angular 应用程序中的功能无法按预期工作
【发布时间】:2020-08-17 18:39:54
【问题描述】:

这是我的 firestore 数据库中的 User 集合:

我正在尝试使用下面的方法只返回Users where isMechanic === false:

private _mechanics = new BehaviorSubject<User[]>([]);

  get mechanics() {
    return this._mechanics.asObservable();
  }

 return of(
      firebase.firestore().collection("users").where("isMechanic", "==", "false")
        .get()
        .then((docs) => {
          const data = []
          docs.forEach((doc) => {
            data.push(doc);
          });
          this._mechanics.next(data)
          console.log('Mechanics in UsersService:', this._mechanics);
          console.log('Mechanics in UsersService:', this.mechanics);
        }).catch((err) => {
          console.log(err);
        })
    );

当前没有记录在调用此方法时,控制台会记录一个空数组。因此,即使(根据屏幕截图)isMechanic 是 false 的记录,也不会返回任何记录。

谁能告诉我这个功能需要做哪些改变才能按预期工作?

【问题讨论】:

  • 首先,isMechanic 在用户中在哪里?
  • 它不起作用,因为isMechanic 不是数组中对象的属性。您是否尝试过查看嵌套属性以查看该属性的位置?例如,在metadata 中。我不使用 Firestore,但我想这应该记录在官方文档中?

标签: angular typescript firebase ionic-framework google-cloud-firestore


【解决方案1】:

我刚才设法弄清楚了。

如果我将"false" 替换为false,则users 集合将按预期过滤。

更换

firebase.firestore().collection("users").where("isMechanic", "==", "false")

firebase.firestore().collection("users").where("isMechanic", "==", false)

仅返回 users 其中isMechanic == false

【讨论】:

    【解决方案2】:

    LoadedMechanics 是一个空数组:

    那么user.isMechanic 肯定是undefinednull

    看下面的例子

    let data = [
    {
    },
    {
       IsMechanic: undefined
    },
    {
       IsMechanic: null
    },
    {
       IsMechanic: false
    }
    ]
    
    console.log(data)
    
    data = data.filter(pr => pr.IsMechanic === false)
    
    console.log(data)

    filter 函数忽略了大多数情况。

    现在的问题是,users 对象是什么?对我来说,它看起来像是一堆文档。 通常要从文档中获取所有属性,您必须使用 ...data() 函数。

    users.map(user => ({
      id: user.id,
      ...user.data()
    }))
    

    你在 this.usersService.users observable 中这样做了吗?

    --编辑

    您可以更改以下代码

    const data = []
    docs.forEach((doc) => {
    data.push(doc);
    this._mechanics.next(data);
    });
    

    const data = docs.docs.map(doc => ({id: doc.id, ...doc.data()}));
    this._mechanics.next(data);
    

    也照docs

    您应该使用文字值过滤布尔属性,而不是双引号

    .where("isMechanic", "==", "false")

    .where("isMechanic", "==", false)

    【讨论】:

    • 感谢您的回答。我已经更新了上面的问题,因为我将在 firebase 中查询数据时尝试过滤数据,而不是在不需要时加载所有用户
    • 更新了答案。在这种情况下,get() 函数返回一个 query 对象,其中包含 emptydocs 等道具。您可以使用 .map(doc =&gt; ({id: doc.id, ...doc.data()})); 将所有文档映射到新的对象数组中
    猜你喜欢
    • 2020-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多