在 firestore 中我有一个名为
wallets
的集合。随机钱包可能看起来像这样
name: "Bank of America"
balance: 4000
currency: "eur"
...
user_id: "PhMbbbbbe0XfVSfSwwaaaaaCMj1"
我设置了一些虚拟安全规则,禁止对钱包进行任何操作
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /wallets/{walletId} {
allow read, write: if false;
}
}
}
我有一个 React Native 项目,它使用
React Native Firebase
与 Firebase 对话
import firestore from '@react-native-firebase/firestore';
import { useEffect, useState } from 'react';
import { useSession } from '../authContext';
export type Wallet = {
name: string;
balance: number;
currency: string;
};
export function useWallets() {
const [wallets, setWallets] = useState<Wallet[]>([]);
const [loading, setLoading] = useState(true);
const {session} = useSession();
useEffect(() => {
const unsubscribe = firestore()
.collection('wallets')
//.where("user_id", "==", session?.user?.uid)
.onSnapshot(snapshot => {
if (!snapshot || snapshot.empty)
return setLoading(false);
const wallets: Wallet[] = [];
snapshot.forEach(doc => {
wallets.push({
name: doc.data().name,
balance: doc.data().balance,
currency: doc.data().currency,
});
});
setWallets(wallets);
setLoading(false);
});
return () => unsubscribe();
}, []);
return { wallets, loading };
}
在上面的代码中,我注释了 where 子句,因为我想测试安全规则。我想确保随机用户无法访问其他用户的数据。奇怪的是,上面的代码返回所有钱包。
我希望它不会返回任何内容。据我的理解,如果规则失败,则读取访问时不会返回任何结果。 而我的规则总是会失败!
为什么我得到了所有钱包?
请记住,Firebase 会在移动设备上缓存数据。因此,如果数据之前是可读的,您可能会看到来自本地缓存的数据(甚至在请求发送到服务器之前)。虽然一旦服务器的响应返回(拒绝它),侦听器将自动取消,但在那个阶段您的应用程序可能已经显示了缓存中的数据。
如果听起来可能是这种情况,您可以通过删除应用程序数据 (Android) 或卸载/重新安装 (iOS) 来擦除缓存。