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

Firebase Firestore数据读取无报错但无显示,求排查解决

问题描述

尝试从Firebase Firestore读取数据,但控制台无错误输出,屏幕也未显示任何数据,求指出问题并提供解决办法。

代码

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
    
class CarDetails extends StatefulWidget {
  const CarDetails({super.key});

  @override
  State<CarDetails> createState() => _CarDetailsState();
}

class _CarDetailsState extends State<CarDetails> {
  final db = FirebaseFirestore.instance;
  final currentUser = FirebaseAuth.instance.currentUser!;

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        backgroundColor: Colors.grey[100],
        appBar: AppBar(
          title: const Text(
            "Car Details",
            style: TextStyle(
              fontWeight: FontWeight.bold,
              fontSize: 20,
            ),
          ),
          centerTitle: true,
        ),
        drawer: const DrawerListBar(),
        body: StreamBuilder<QuerySnapshot>(
            stream: db
                .collection(currentUser.uid)
                .doc()
                .collection("vehicle details")
                .snapshots(),
            builder: (context, snapshot) {
              if (snapshot.hasError) {
                return Text("ERROR: ${snapshot.error}");
              } else if (snapshot.hasData) {
                return ListView.builder(
                    itemCount: snapshot.data!.docs.length,
                    itemBuilder: (context, index) {
                      var carDetails = snapshot.data!.docs[index];
                      return GestureDetector(
                        onTap: () {},
                        child: Container(
                          margin: const EdgeInsets.only(bottom: 20),
                          child: Stack(
                            children: [
                              const SizedBox(height: 20),
                              Container(
                                width: double.infinity,
                                margin: const EdgeInsets.only(
                                    left: 24, right: 24, top: 50),
                                padding: const EdgeInsets.only(
                                    left: 25, bottom: 15, right: 20, top: 10),
                                decoration: BoxDecoration(
                                  borderRadius: BorderRadius.circular(20),
                                  color: const Color(0xFF203e5a),
                                ),
                                child: Column(
                                  crossAxisAlignment: CrossAxisAlignment.start,
                                  children: [
                                    Text(
                                      carDetails["number plate"],
                                      style: const TextStyle(
                                        fontWeight: FontWeight.bold,
                                        fontSize: 25,
                                        color: Colors.white,
                                      ),
                                    ),
                                    const Text(
                                      "price/hr",
                                      style: TextStyle(
                                        fontWeight: FontWeight.bold,
                                        fontSize: 25,
                                        color: Colors.white,
                                      ),
                                    ),
                                    const SizedBox(height: 15),
                                    Row(
                                      mainAxisAlignment:
                                          MainAxisAlignment.spaceBetween,
                                      children: [
                                        CarItems(
                                            name: "Brand",
                                            value: carDetails["brand"]),
                                        CarItems(
                                            name: "Model",
                                            value: carDetails["model"]),
                                        CarItems(
                                            name: "Year",
                                            value: carDetails["year"]),
                                        CarItems(
                                            name: "Mileage",
                                            value: carDetails["mileage"]),
                                      ],
                                    ),
                                  ],
                                ),
                              ),
                              Positioned(
                                right: 30,
                                child: Image.asset("Images/rolls_royce.png"),
                              ),
                            ],
                          ),
                        ),
                      );
                    });
              } else {
                return const Text("No data");
              }
            }),
      ),
    );
  }
}

Firebase集合结构截图

Firebase集合结构截图1
Firebase集合结构截图2


问题分析与解决办法

核心问题

代码中Firestore路径错误:db.collection(currentUser.uid).doc().collection("vehicle details")里的.doc()是无参调用,会生成一个随机ID的新文档引用,而非指向你Firebase中已存在的文档。这导致你查询的是一个不存在的文档下的子集合,自然拿不到数据。

解决步骤

  1. 修正Firestore查询路径
    根据你的Firebase截图,正确路径应为「用户UID集合 → 具体文档ID → "vehicle details"子集合」。把.doc()替换成你Firebase中实际存在的文档ID,示例:

    stream: db
        .collection(currentUser.uid)
        .doc("你的文档ID") // 替换为截图中显示的文档ID,如类似"abc123"的字符串
        .collection("vehicle details")
        .snapshots(),
    

    若需查询用户UID集合下所有文档的"vehicle details"子集合,可使用集合组查询:

    stream: db.collectionGroup("vehicle details").where(FieldPath.documentId, isEqualTo: currentUser.uid).snapshots(),
    

    注意使用集合组查询需在Firebase控制台创建对应索引。

  2. 添加调试日志
    在else if (snapshot.hasData)分支中加入打印语句,确认是否获取到数据:

    else if (snapshot.hasData) {
      print("获取到的数据条数:${snapshot.data!.docs.length}"); // 新增调试日志
      return ListView.builder(...);
    }
    

    可通过控制台输出判断数据是否返回,辅助排查问题。

  3. 检查Firestore安全规则
    确保安全规则允许当前认证用户读取目标路径数据,示例规则:

    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        match /{userId}/{document=**} {
          allow read, write: if request.auth != null && request.auth.uid == userId;
        }
      }
    }
    

    该规则允许认证用户读写自己UID下的所有文档及子集合。


内容的提问来源于stack exchange,提问作者I Can Done

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 08:12:03