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

Flutter:如何检查Firebase Firestore指定文档ID是否存在及代码修复

解决Firebase Auth手机号获取与Firestore文档检查的跳转问题

看起来你的代码核心问题出在异步操作的时机管理和潜在的空值异常上,我帮你整理了修复后的代码,同时会逐一解释关键修改点:

修正后的完整代码

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:loginpage/AccountDetialsPage.dart';
import 'package:loginpage/Pricepage.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  String? globalNumber; // 用可空类型处理潜在的空值
  late FirebaseFirestore firestore;

  @override
  void initState() {
    super.initState();
    firestore = FirebaseFirestore.instance; // 新版本Firestore初始化方式
    // 如果你用的是旧版依赖,替换成 Firestore.instance 即可
    _loadCurrentUser(); // 异步加载用户信息
  }

  // 异步获取当前用户并处理手机号
  Future<void> _loadCurrentUser() async {
    final FirebaseAuth _auth = FirebaseAuth.instance;
    final User? user = await _auth.currentUser; // 新版Firebase Auth的用户类型

    if (user != null && user.phoneNumber != null) {
      setState(() {
        globalNumber = user.phoneNumber;
      });
    } else {
      // 处理获取不到用户/手机号的情况
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('无法获取用户信息,请重新登录')),
      );
      // 可选:直接跳转到登录页
      // Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => LoginPage()));
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: const Center(child: Text('Welcome')),
      bottomNavigationBar: SizedBox(
        height: 50,
        child: RaisedButton(
          color: Colors.red,
          child: const Text('Next', style: TextStyle(color: Colors.white)),
          onPressed: () async {
            // 先检查手机号是否加载完成
            if (globalNumber == null) {
              ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(content: Text('用户信息未加载完成,请稍后再试')),
              );
              return;
            }

            // 查询Firestore文档
            final snapShot = await firestore.collection('users').doc(globalNumber).get();
            
            if (snapShot.exists) {
              Navigator.push(context, MaterialPageRoute(builder: (_) => Pricepage()));
            } else {
              Navigator.push(context, MaterialPageRoute(builder: (_) => AccountDetialsPage()));
            }
          },
        ),
      ),
    );
  }
}

关键修改点说明

  • 异步操作的状态同步:
    原代码中getCurrentUser是异步方法,但在initState里直接调用没有等待,导致用户点击按钮时globalNumber可能还未赋值。现在用_loadCurrentUser异步方法,并通过setState更新状态,确保UI能感知到手机号的加载完成。
  • 空值安全防护:
    将globalNumber改为可空类型String?,同时检查user和user.phoneNumber是否为null,避免空指针异常。点击按钮时也先校验globalNumber的有效性,防止无效的Firestore查询。
  • 移除嵌套的MaterialApp:
    原代码中HomePage内部嵌套了MaterialApp,这会导致Navigator的上下文混乱(每个MaterialApp都有独立的Navigator栈)。通常MaterialApp只需要在应用根Widget中使用,所以这里直接返回Scaffold。
  • Firestore版本兼容:
    标注了新旧版本Firestore的初始化写法,你可以根据自己的依赖版本灵活调整。
  • 用户体验优化:
    添加了SnackBar提示,在加载未完成或获取失败时给用户明确反馈。

额外注意事项

  1. 确保你的firebase_auth和cloud_firestore依赖版本兼容,如果用的是旧版依赖(如firebase_auth: ^0.20.0),需要把User?改回FirebaseUser,currentUser改回currentUser()方法。
  2. 只有用户通过手机号登录时,user.phoneNumber才会有值,如果用户用邮箱/第三方账号登录,这个字段会是null,需要额外处理这种场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 19:12:39