Flutter 和 Firestore 在请求中没有用户信息

Posted

技术标签:

【中文标题】Flutter 和 Firestore 在请求中没有用户信息【英文标题】:Flutter and Firestore does not have user information in request 【发布时间】:2018-08-28 19:27:15 【问题描述】:

使用flutter,我已经安装了firebase-auth 和firestore 软件包,只要我对用户没有任何规则,我就能够通过firebase auth 进行身份验证并调用firestore。

我有一个调用 _handleEmailSignIn 的按钮,我确实得到了一个有效用户(因为他们在 Firebase Auth DB 中)

import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

final FirebaseAuth _auth = FirebaseAuth.instance;

void _handleEmailSignIn(String email, String password) async 
  try 
    FirebaseUser user = await _auth.signInWithEmailAndPassword(
        email: email, password: password);

    print("Email Signed in " + user.uid);  // THIS works
   catch (err) 
    print("ERROR CAUGHT: " + err.toString());
  

然后我有另一个按钮调用此函数以尝试将记录添加到testing123 集合中。

Future<Null> _helloWorld() async 
  try 
    await Firestore.instance
        .collection('testing123')
        .document()
        .setData(<String, String>'message': 'Hello world!');
    print('_initRecord2 DONE');
   catch (err) 
    print("ERROR CAUGHT: " + err.toString());
  

现在只要我没有关于检查请求用户的任何规则,它就可以工作。这行得通...

service cloud.firestore 
  match /databases/database/documents 
    match /testing123auth/doc 
        allow read, create
    
  

当我想确保我拥有与 _handleEmailSignIn 一起使用的经过身份验证的用户时,这不会提供 PERMISSION_DENIED: Missing or insufficient permissions.

service cloud.firestore 
  match /databases/database/documents 
    match /testing123auth/doc 
        allow read, create: if request.auth != null;
    
  

我怀疑 firestore 请求不包括 firebase 用户。我是要配置 firestore 以包含用户,还是应该自动作为 firebase 的一部分?

【问题讨论】:

我最近看到了一个类似行为的问题,其中google-services.json 没有放在正确的位置。 我相信这一切都可以正常工作,因为 google 登录也可以使用......只是 firebase 登录(电子邮件或 google 登录)用户结果不会转移到 firestore 请求。 这也是另一个问题中的行为。 如果你能找到那我可以看看 ***.com/questions/49245019/… 【参考方案1】:

我会建议制定如下规则:

service cloud.firestore 
  match /databases/database/documents 
   match /testing123auth/documents=** 
    allow read, create: if true;
    
  

或者,更好的是,限制用户的范围:

service cloud.firestore 
  match /databases/database/documents 
    match /testing123auth/userId 
      allow read, create: 
        if (request.auth.uid != null &&
            request.auth.uid == userId); // DOCUMENT ID == USERID
       // END RULES FOR USERID DOC
      
      // IF YOU PLAN TO PUT SUBCOLLECTIONS INSIDE DOCUMENT:
      match /documents=** 
        // ALL DOCUMENTS/COLLECTIONS INSIDE THE DOCUMENT
        allow read, write:
          if (request.auth.uid != null &&
            request.auth.uid == userId);
       // END DOCUMENTS=**
     // END USERID DOCUMENT
  

【讨论】:

【参考方案2】:

需要注意的一点是,firebase_core 是将所有服务连接在一起的“胶水”,当您使用 Firebase 身份验证和其他 Firebase 服务时,您需要确保获得实例来自相同的 firebase 核心应用程序配置。

final FirebaseAuth _auth = FirebaseAuth.instance;

如果您使用多个 Firebase 服务,则不应使用上述这种方式。 相反,您应该始终从 FirebaseAuth.fromApp(app) 获取 FirebaseAuth,并使用相同的配置来获取所有其他 Firebase 服务。

FirebaseApp app = await FirebaseApp.configure(
   name: 'MyProject',
   options: FirebaseOptions(
      googleAppID: Platform.isandroid ? 'x:xxxxxxxxxxxx:android:xxxxxxxxx' : 'x:xxxxxxxxxxxxxx:ios:xxxxxxxxxxx',
      gcmSenderID: 'xxxxxxxxxxxxx',
      apiKey: 'xxxxxxxxxxxxxxxxxxxxxxx',
      projectID: 'project-id',
      bundleID: 'project-bundle',
   ),
 );
 FirebaseAuth _auth = FirebaseAuth.fromApp(app);
 Firestore _firestore = Firestore(app: app);
 FirebaseStorage _storage = FirebaseStorage(app: app, storageBucket: 'gs://myproject.appspot.com');

这可确保所有服务都使用相同的应用配置,并且 Firestore 将接收身份验证数据。

【讨论】:

【参考方案3】:

firestore 不需要任何特殊配置来执行此操作。

这就是您所需要的。 修改自Basic Security Rules:

service cloud.firestore 
  match /databases/database/documents 
    match /testing123/document=** 
      allow read, write: if request.auth.uid != null;
    
  

他们似乎检查uid 是否为null 而不是auth 本身。试试这个,看看它是否有效。此外,您的代码似乎不一致,因为 firestore 规则有 testing123auth 而flutter 有 testing123。我不确定这是不是故意的。

【讨论】:

这不是 OP 所要求的 @dark_ruby 你能详细说明一下吗? OP 询问“我是要配置 firestore 以包含用户,还是应该作为 firebase 的一部分自动进行?”我想通过说不需要特殊配置来回答他们的问题,并添加了一些可能有助于解决他们问题的信息。 问题是关于客户端配置而不是服务器。 @dark_ruby 问题是关于一般配置的,并且 OP 确实通过在问题中添加了他们对 firestore 规则的尝试来包含服务器端配置。 再次正确阅读问题的标题,这是关于不包含用户信息的请求。那只能包含在客户端中。问题主体也已经提到了服务器端配置。实际上,您只是在“答案”中复制了部分问题。【参考方案4】:

要检查用户是否已登录,您应该使用

request.auth.uid != null

【讨论】:

以上是关于Flutter 和 Firestore 在请求中没有用户信息的主要内容,如果未能解决你的问题,请参考以下文章

Flutter Firestore [cloud_firestore/not-found] 找不到某些请求的文档

Firestore 规则使用 Flutter 客户端验证时间戳

Flutter bloc 在 7.2.0 版本中没有用 Equatable 重建

在 Flutter 应用程序上过滤和排序 Firebase (Firestore) 数据

Flutter:Firebase 身份验证和 Firestore 快照流

Flutter:在 Firestore/实时数据库中存储和检索格式化文本