开发者问题收集

如何将 VueUse useFirestore() 与 Where QueryConstraint 结合使用?

2022-09-14
262

我有一个 Firestore users 文档,其内容如下:

{
    currentCompanyId: "123",
    displayName: "Mary Jane" 
}

还有一个 Firestore websites 文档,其内容如下:

{
    companyId: "123",
    homePageUrl: "https://www.google.com/"
}

现在,我尝试使用 VueUse useFirestore() 包装器来显示 websites 文档。

为此,我在 where 查询约束内引用了 users 文档的 currentCompanyId 属性,如下所示:

<template>
  <div>
    {{ websites?.[0] }}
  </div>
</template>

<script setup lang="ts">
import { useAuth } from '@vueuse/firebase/useAuth';
import { useFirestore } from '@vueuse/firebase/useFirestore';
import { collection, doc, query, where } from 'firebase/firestore';
import { auth, db } from 'src/config/firebase';
import { User } from 'src/types';
import { computed } from 'vue';

const { user: authUser } = useAuth(auth);
const userDocRef = doc(db, `users/${authUser.value?.uid}`);
const user = useFirestore<User>(userDocRef);

const websiteQuery = computed(() =>
  query(
    collection(db, 'websites'),
    where('companyId', '==', user.value?.currentCompanyId) // This produces an error
    // where('companyId', '==', '123') // This works, but is not practical
  )
);
const websites = useFirestore(websiteQuery);
</script>

companyId 值进行硬编码 123 有效。

但每当我在计算的引用中使用 user.value?.currentCompanyId 时,它都会引发一个错误,提示如下:

TypeError: right-hand side of 'in' should be an object, got null

2个回答

仅当值定义如下时,才尝试传递 QueryConstraint

const websiteQuery = computed(() => {
  const queryContraints: any = [];
  const currentCompanyId = user.value?.currentCompanyId;

  if (currentCompanyId) queryContraints.push(where("companyId", "==", currentCompanyId));
  return query(
    collection(db, 'websites'),
    ...queryContraints
  )
});

但是,如果您不提供 where() 约束,这将返回所有文档,因此也许仅在定义时(即在身份验证状态加载后)尝试运行查询。 onAuthStateChanged() 在这里可能很有用。

Dharmaraj
2022-09-14

我搞明白了。

问题是 user.value?.currentCompanyId 最初为 null

以下是错误消息:

TypeError: right-hand side of 'in' should be an object, got null

它基本上是在说 Where 查询约束的右侧应该是一个对象,但它却为空。

将查询包装在 computed 引用中最终会在更新时将值从 null 更改为其他值。但最初它是 null 。这就是错误的原因。

为了解决这个问题,您可以在 useFirestore 中设置 user 的一些初始属性。因此, Where 查询约束最初将使用该非空值。即使是空字符串也可以。您可以使用任何非 null 的值。

以下是完整代码:

<template>
  <div>
    {{ websites?.[0] }}
  </div>
</template>

<script setup lang="ts">
import { useAuth } from '@vueuse/firebase/useAuth';
import { useFirestore } from '@vueuse/firebase/useFirestore';
import { collection, doc, query, where } from 'firebase/firestore';
import { auth, db } from 'src/config/firebase';
import { User } from 'src/types';
import { computed } from 'vue';

const { user: authUser } = useAuth(auth);
const userDocRef = doc(db, `users/${authUser.value?.uid}`);
const user = useFirestore<User>(userDocRef, { currentCompanyId: '' }); // <-- See change here

const websiteQuery = computed(() =>
  query(
    collection(db, 'websites'),
    where('companyId', '==', user.value?.currentCompanyId)
  )
);
const websites = useFirestore(websiteQuery);
</script>
TinyTiger
2022-09-19