【问题标题】:Unable to get client data to display [firestore]无法获取要显示的客户端数据 [firestore]
【发布时间】:2019-03-04 07:04:43
【问题描述】:

我的数据库设置为 /clients 并使用 firebase auth 来处理用户。我想让它让用户只能查看、编辑和删除他们创建的客户端数据。当前的 Firestore 安全规则是。

[code]service cloud.firestore {
  match /databases/{database}/documents {
    // Make sure the uid of the requesting user matches name of the user
    // document. The wildcard expression {userId} makes the userId variable
    // available in rules.
    match /clients/{userId} {
      allow read, update, delete: if request.auth.uid == userId;
      allow create: if request.auth.uid != null;
    }
  }
}[/code]

使用此规则,用户可以将新客户端添加到数据库中,但网站上的客户端不会显示。我有代码设置,以便当用户添加客户端时,它将用户 UID 附加到“userId”下的客户端。显示客户端的代码是

[code]<tbody>
                    {clients.map(client => (
                        <tr key={client.id}>
                            <td>{client.firstName} {client.lastName}</td>
                            <td>{client.dateCreated}</td>
                            <td><a href={`tel:${client.phone}`}>{client.phone}</a></td>
                            <td>
                                <Link to={`/client/${client.id}`} className="btn btn-secondary btn-sm">
                                    <i className="fas fa-arrow-circle-right"></i> Details
                                </Link>
                            </td>
                        </tr>
                    ))}
                 </tbody>

[/代码]

我不确定我做错了什么,是安全规则还是我选择显示数据的方式?

【问题讨论】:

    标签: reactjs firebase-authentication firebase-security


    【解决方案1】:

    我的理解是您有一个客户集合和一个用户集合。用户可以创建客户端,并且只能查看/编辑/删除他们创建的客户端,对吗?如果是这样,只需添加一个 createdBy(可以是任何内容)字段,其中包含创建特定客户端的用户 uid,并检查该字段是否等于您从 auth 对象获得的 uid:

    service cloud.firestore {
      match /databases/{database}/documents {
        match /clients/{clientId} {
          // only user who created the client can read/update/delete it
          allow read, update, delete: if resource.data.createdBy == request.auth.uid;
          // logged user only can create a client
          allow create: if request.auth.uid != null;
        }
      }
    }
    

    通配符 {clientId} 只是在这里说“嘿,此规则适用于 clients/ 集合下的任何文档”。借助 resource.data 对象,您可以获取存储在文档中的数据。

    文档中列出了所有内容:https://firebase.google.com/docs/firestore/security/get-started

    【讨论】:

    • 使用这条规则我仍然遇到同样的问题,我可以创建客户端但无法在网站上查看它们。
    【解决方案2】:

    我能够得到我的结果,但不是通过安全规则。在调整了安全规则和我的数据库变量以便将用户 ID 附加到他们添加的数据之后,我尝试了 @firebaser 建议的规则。如上所述,我能够根据该规则创建客户端,但是我无法查看它们,并且在控制台中出现“配置文件侦听器错误:缺少或不足的权限。FirebaseError:缺少或不足的权限”。

    根据错误,我似乎必须编辑我的项目文件夹的节点模块中的一个 firebase 文件。我不想冒险修改这些文件,因此我没有使用安全规则过滤数据,而是更改了客户端数据的显示方式。我在.map 函数之前添加了.filter,这样它只会显示链接到用户ID 的客户端。而我的安全规则只允许登录用户读写数据。 [代码]

    <tbody>
                {clients.filter(client => client.userId === firebase.auth().currentUser.uid).map(client => (
                    <tr key={client.id}>
                        <td>{client.firstName} {client.lastName}</td>
                        <td>{client.dateCreated}</td>
                        <td><a href={`tel:${client.phone}`}>{client.phone}</a></td>
                        <td>
                            <Link to={`/client/${client.id}`} className="btn btn-secondary btn-sm">
                                <i className="fas fa-arrow-circle-right"></i> Details
                            </Link>
                        </td>
                    </tr>
                ))}
             </tbody>
    

    [/代码]

    我无法真正告诉任何人这种方法有多安全,但它确实有效。

    【讨论】:

    • 您当然会遇到错误...安全规则的设计应适合您的客户查询。最好编写一个查询来获取具有 userId === 当前用户 ID 的客户端,而不是过滤数组...const query = db.collection('clients').where('userId', '==, 'theCurrentUserId') ...如果您编写规则以仅获取与条件匹配的文档:您必须编写也符合此条件的查询。
    猜你喜欢
    • 2019-07-10
    • 2019-12-11
    • 1970-01-01
    • 2022-07-01
    • 2014-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多