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

Flutter中通过Firebase Firestore获取用户类型实现页面路由跳转

解决Flutter中Firestore获取userType并路由页面的问题

核心实现步骤

以下是可直接复用的代码逻辑,包含用户类型获取、路由跳转及常见问题排查:

1. 基础初始化与路由配置

确保Firebase初始化完成,并在MaterialApp中定义目标页面路由:

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: const AuthCheckPage(),
      routes: {
        '/merchant': (context) => const MerchantPage(),
        '/customer': (context) => const CustomerPage(),
        '/login': (context) => const LoginPage(),
      },
    );
  }
}

2. 获取用户类型并路由

通过FutureBuilder处理异步请求,根据返回的userType字段跳转对应页面:

class AuthCheckPage extends StatelessWidget {
  const AuthCheckPage({super.key});

  Future<String?> getUserType() async {
    final currentUser = FirebaseAuth.instance.currentUser;
    if (currentUser == null) return null;

    try {
      // 替换为你的用户集合名称,确保字段名userType与Firestore中一致
      final userDoc = await FirebaseFirestore.instance
          .collection('users')
          .doc(currentUser.uid)
          .get();

      if (userDoc.exists) {
        return userDoc.data()?['userType'] as String?;
      } else {
        print("用户文档不存在");
        return null;
      }
    } catch (e) {
      print("获取用户类型失败: $e");
      return null;
    }
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<String?>(
      future: getUserType(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Center(child: CircularProgressIndicator());
        }

        if (snapshot.hasError) {
          return const Center(child: Text("加载失败,请重试"));
        }

        final userType = snapshot.data;
        if (userType == null) {
          // 未登录或用户文档异常,跳转登录页
          WidgetsBinding.instance.addPostFrameCallback((_) {
            Navigator.pushReplacementNamed(context, '/login');
          });
          return const SizedBox.shrink();
        }

        // 根据用户类型跳转对应页面
        WidgetsBinding.instance.addPostFrameCallback((_) {
          Navigator.pushReplacementNamed(
            context,
            userType == 'merchant' ? '/merchant' : '/customer',
          );
        });
        return const SizedBox.shrink();
      },
    );
  }
}

3. 示例页面实现

// 商家页面
class MerchantPage extends StatelessWidget {
  const MerchantPage({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(body: Center(child: Text("商家专属页面")));
  }
}

// 顾客页面
class CustomerPage extends StatelessWidget {
  const CustomerPage({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(body: Center(child: Text("顾客专属页面")));
  }
}

// 登录页面
class LoginPage extends StatelessWidget {
  const LoginPage({super.key});

  @override
  Widget build(BuildContext context) {
    return const Scaffold(body: Center(child: Text("请先登录")));
  }
}

常见问题排查

  • 字段/集合名称错误:检查Firestore中集合名(如users)、字段名(如userType)是否与代码完全一致,大小写敏感。
  • 权限问题:确保Firestore安全规则允许用户读取自己的文档,示例规则:
    rules_version = '2';
    service cloud.firestore {
      match /databases/{database}/documents {
        match /users/{userId} {
          allow read: if request.auth != null && request.auth.uid == userId;
        }
      }
    }
    
  • 异步处理错误:避免在Future未完成时判断字段值,必须等待snapshot.connectionState完成后再处理。
  • 用户未登录:确认currentUser不为null,否则需引导用户登录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 23:35:41