如何将 VueUse useFirestore() 与 Where QueryConstraint 结合使用?
我有一个 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
仅当值定义如下时,才尝试传递
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()
在这里可能很有用。
我搞明白了。
问题是
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>