You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter应用Firestore规则request.auth != null无数据返回问题

问题:Firestore设置认证规则后Flutter应用无法读取数据

问题背景

使用Flutter开发应用,配置Firestore安全规则要求用户必须认证(request.auth != null)后,尽管已有两个测试账号完成注册并登录,应用仍无法在ListView中以卡片形式展示Firestore中的数据。Firebase与应用通信正常,用户UID已分配,但数据无法加载。

当前Firestore安全规则

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
  
  match /Events {
    allow read, write: if request.auth != null;
  
  }

  }
}

Flutter核心代码(HomePage)

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:plancel/components/event_card.dart';
import 'package:plancel/components/menu_drawer.dart';
import 'package:plancel/settings.dart';

class HomePage extends StatelessWidget {
  HomePage({super.key});

  final user = FirebaseAuth.instance.currentUser!;

  // 退出登录方法
  void signUserOut() {
    FirebaseAuth.instance.signOut();
  }

  @override
  Widget build(BuildContext context) {

    // 跳转到设置页
    void goToSettingsPage() {
      Navigator.pop(context);
      Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => const SettingsPage(),
          ));
    }

    return Scaffold(
      backgroundColor: Colors.grey[300],
      appBar: AppBar(
        backgroundColor: Colors.grey[900],
        title: const Text(
          'APP NAME',
          style: TextStyle(
            color: Colors.white,
            fontSize: 30,
            fontWeight: FontWeight.w300,
          ),
        ),
        centerTitle: true,
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.pushNamed(context, '/eventform');
        },
        backgroundColor: Colors.grey[900],
        child: const Icon(Icons.add),
      ),
      drawer: MenuDrawer(
        onSettingsTap: goToSettingsPage,
        onSignOut: signUserOut,
      ),
      body: StreamBuilder(
        stream: FirebaseFirestore.instance
            .collection("Events")
            .orderBy("date", descending: false)
            .snapshots(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return ListView.builder(
              itemCount: snapshot.data!.docs.length,
              itemBuilder: (context, index) {
                final post = snapshot.data!.docs[index];
                return EventCard(
                    titleEvent: post['eventTitle'],
                    locationEvent: post['eventLocation'],
                    dateEvent: post['date'],
                    timeHour: post['timeHour'],
                    timeMinute: post['timeMinute'],
                );
              },
            );
          } else if (snapshot.hasError) {
            return Center(
              child: Text('错误${snapshot.error}'),
            );
          }
          return const Center(child: CircularProgressIndicator());
        },
      ),
    );
  }
}

错误提示

错误截图显示权限被拒绝(Permission denied),说明Firestore读取请求未通过规则校验。

解决方案

1. 修正Firestore规则路径匹配

当前规则仅匹配Events集合本身,而读取集合内的文档需要匹配到文档层级。修改规则为:

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    // 使用通配符匹配集合下所有文档及子集合
    match /Events/{document=**} {
      allow read, write: if request.auth != null;
    }
  }
}

2. 确保认证状态稳定后再请求数据

原代码中直接获取currentUser!可能存在初始化时用户未完成认证的情况,建议先监听认证状态,确认用户登录后再加载Firestore数据流:

body: StreamBuilder<User?>(
  stream: FirebaseAuth.instance.authStateChanges(),
  builder: (context, authSnapshot) {
    if (authSnapshot.hasData && authSnapshot.data != null) {
      // 用户已登录,加载Firestore数据
      return StreamBuilder<QuerySnapshot>(
        stream: FirebaseFirestore.instance
            .collection("Events")
            .orderBy("date", descending: false)
            .snapshots(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return ListView.builder(
              itemCount: snapshot.data!.docs.length,
              itemBuilder: (context, index) {
                final post = snapshot.data!.docs[index];
                return EventCard(
                  titleEvent: post['eventTitle'],
                  locationEvent: post['eventLocation'],
                  dateEvent: post['date'],
                  timeHour: post['timeHour'],
                  timeMinute: post['timeMinute'],
                );
              },
            );
          } else if (snapshot.hasError) {
            return Center(child: Text('错误:${snapshot.error}'));
          }
          return const Center(child: CircularProgressIndicator());
        },
      );
    } else {
      // 用户未登录,显示登录提示或跳转登录页
      return const Center(child: Text('请先登录'));
    }
  },
),

3. 验证数据写入权限

如果Firestore中的测试数据是在规则生效前写入的,需确认这些文档的读取权限已被当前规则覆盖,或重新由已认证用户写入数据。

内容的提问来源于stack exchange,提问作者Mutant52

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 11:13:21