任何人都知道为啥我会收到“快照侦听器中未捕获的错误:FirebaseError:缺少权限或权限不足”吗?

Posted

技术标签:

【中文标题】任何人都知道为啥我会收到“快照侦听器中未捕获的错误:FirebaseError:缺少权限或权限不足”吗?【英文标题】:Anybody knows why I get the 'Uncaught Error in snapshot listener: FirebaseError: Missing or insufficient permissions'?任何人都知道为什么我会收到“快照侦听器中未捕获的错误:FirebaseError:缺少权限或权限不足”吗? 【发布时间】:2021-05-23 20:48:50 【问题描述】:

我目前正在研究如何使用 firebase,但我无法找到一种方法来仅让用户更新、删除或读取他们添加的图像(集合)。

这是我的 Firestore 结构:

这是我使用的安全规则:

match /databases/database/documents 
    match /document=** 
    function authed()
        return request.auth != null
    
    function matchesUser()
        return request.auth.uid == data.userId
    
    
    allow read: if authed() && matchesUser(resource.data)
    allow create: if authed() && matchesUser(request.resource.data)
    

当我尝试获取数据/读取图像(集合)时,我得到Uncaught Error in snapshot listener: FirebaseError: Missing or insufficient permissions

这是我尝试从 firestore 读取数据的代码

import  useState, useEffect  from 'react'
import projectFirestore from '../firebase/firebase'
import useAuth from '../contexts/AuthContext'

const useFirestore = (collection) => 
    const [docs, setDocs] = useState([])
    const currentUser = useAuth()

    useEffect(() => 
        const unsub = projectFirestore.collection(collection)
        .orderBy('createdAt', 'desc')
        .where("userId", "==", currentUser.uid)
        .onSnapshot((snap) => 
            let documents = []
            snap.forEach(doc => 
                documents.push(...doc.data(), id: doc.id)
            )
            setDocs(documents)
        )
        return () => unsub()
    , [collection, currentUser])

    return docs


export default useFirestore

这是我尝试让用户将文件上传到 firebase 的代码:

import useState, useEffect from 'react';
import projectStorage, projectFirestore, timestamp from '../firebase/firebase'
import useAuth from '../contexts/AuthContext'

const useStorage = (file) => 
    const [progress, setProgress] = useState(0)
    const [error, setError] = useState(null)
    const [url, setUrl] = useState(null)

    const currentUser = useAuth()

    useEffect(() => 
        // references
        const storageRef = projectStorage.ref(file.name)
        const collectionRef = projectFirestore.collection('images')

        storageRef.put(file).on('state_changed', (snap) => 
            let percentage = (snap.bytesTransferred / snap.totalBytes) * 100
            setProgress(percentage)
        , (err) => 
            setError(err)
        , async () => 
            const url = await storageRef.getDownloadURL()
            const createdAt = timestamp();
            collectionRef.add(
                url,
                userId: currentUser.uid, 
                createdAt
            )
            setUrl(url)
        )
    , [file])

    return  progress, error, url 


export default useStorage

【问题讨论】:

您的matchesUser() 函数似乎缺少data 参数? function matchesUser(data) return request.auth.uid == data.userId 这似乎是一个答案@samthecodingman。 :) 非常感谢您的回答,是的,它有效。现在我明白为什么它一开始不起作用了。 @FrankvanPuffelen 只有这么多,我才能在公交车上用手机打字而不会晕车。目的是稍后在我的电脑上回到它哈哈。它现在已适当补水作为答案。 谢谢山姆!以及能够在公共汽车上打字的荣誉???? 【参考方案1】:

使用您在安全规则中创建的matchesUser() 函数时,您传入一个包含文档数据的参数。但是,在您定义函数的位置,此参数未定义 - 导致您尝试读取未定义对象的 userId 属性时出现语法错误。

应该定义为:

function matchesUser(data) 
  return request.auth.uid == data.userId

您收到FirebaseError: Missing or insufficient permissions 错误的原因是因为安全规则中的所有语法错误都被视为false(即拒绝访问)。以后要发现这样的错别字,您可以使用Security Rules Playground 或使用Security Rules Emulator 测试您的规则。

【讨论】:

是的,它就像你之前说的那样工作。傻我,虽然我应该更加小心。在你刚刚告诉我我错过了data参数后我明白了哈哈哈。非常感谢你,我真的很感激。 @HafizhFarhandika 如果这回答了您的问题,请不要忘记接受它作为答案。很高兴我能帮上忙。

以上是关于任何人都知道为啥我会收到“快照侦听器中未捕获的错误:FirebaseError:缺少权限或权限不足”吗?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我会收到此错误:未捕获的类型错误:无法读取 null 的属性 'classList'

知道为啥我会收到此错误吗?

我不知道为啥我会收到分段错误错误

谁能向我解释为啥我会收到 Stack Overflow 错误?

为啥我会收到此错误:“class app\Laptop not found?”

为啥我会收到这个语法错误(false syntax error pyflakes)