根据firestore数据库文档存在情况显示小部件

问题描述 投票:0回答:1

我对 Flutter 移动开发完全陌生。 我想要实现的是拥有一个经过身份验证的用户(在应用程序中),该用户也连接到 Instagram 帐户。我使用 进行 以及 [标签:Cloud Firestore 数据库]。我的想法如下:

  • 使用 Firebase 中的身份验证服务对用户进行身份验证,经过身份验证后,我将拥有一个唯一的 UID,如下图所示:user entry in authentication service in Firebase

  • 用户连接 Instagram 帐户并设置一些首选项后,在 Firestore 数据库中添加一个具有与经过身份验证的用户相同的 UID 的文档以及与 Instagram 帐户相关的其他数据。

为了在应用程序中做到这一点,我在 main.dart 文件中实现了这个简单的代码:

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart' hide EmailAuthProvider;
import 'package:firebase_ui_auth/firebase_ui_auth.dart';

import 'package:main/routingPage.dart';

/// create firestore instace to use in the rest of the code
var db = FirebaseFirestore.instance;

void main() async{
  /// Initialize Firebase
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  /// Run app
  runApp(MyApp());
}

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
       home: StreamBuilder<User?>(
            stream: FirebaseAuth.instance.authStateChanges(),
            builder: (context, snapshot) {
              /// If the user is not logged in, I ask him to log in or subscribe
              if (!snapshot.hasData) {
                return SignInScreen(
                  providers: [
                    EmailAuthProvider(),
                  ],
                );
              }
              /// If the user is logged in I proceed on the routingPage
              else {
                return routingPage();
              }
            },
       )
    );
  }
}

身份验证后,(本例是在路由页面,但我不知道这是否是正确的方法)我需要做一个简单的操作:检查与经过身份验证的用户具有相同UID的文档是否已经存在于是否 Firestore 数据库。

  • 如果文档存在,请在应用程序的主页面上继续。

  • 如果文档不存在,则将用户发送到引导程序以连接其 Instagram 并选择一些首选项,创建文档,然后返回主页面。

现在已经两天了,我完全陷入困境。我不知道如何有效地实施它,这是否是正确的方法,是否有更精简的实施等等。

我想获得架构级别的帮助,因为我不仅需要登录,还需要登录 + Instagram 连接。你将如何进行?最好的方法是什么?

非常感谢您成为我的帮手!

flutter firebase dart google-cloud-firestore firebase-authentication
1个回答
0
投票

就我个人而言,我的方法是将用户发送到启动屏幕,因此,

home
将是
SplashScreen
,然后在启动屏幕的
initState
上,我们调用启动检查未来的函数,并使用
 .then
推至相应屏幕

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

class SplashScreen extends StatefulWidget {
  const SplashScreen({super.key});

  @override
  State<SplashScreen> createState() => _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen> {
  // This function will be somewhere else(for architecture's sake)
  Future<bool> checkIfUserExists({
    required FirebaseAuth auth,
    required FirebaseFirestore store,
  }) async {
    if (auth.currentUser == null) return false;
    final userDoc =
        await store.collection('users').doc(auth.currentUser!.uid).get();
    return userDoc.exists;
  }

  @override
  void initState() {
    super.initState();
    checkIfUserExists(
      auth: FirebaseAuth.instance,
      store: FirebaseFirestore.instance,
    ).then((userExists) {
      if(userExists) return Navigator.pushNamed(context, '/home');
      Navigator.pushNamed(context, '/login');
    });
    // When you take them to login, over there, you will use the auth 
    // instance to log them in and after that, 
    // FirebaseAuth.instance.currentUser will no longer be null, then you'll 
    // fetch the user's data from the Firestore with their currentUser.uid.
    
    // For sign-up, after they sign-up, you go ahead and create a document 
    // for them using their uid
    
    // await FirebaseFirestore.instance.collection('users').doc(FirebaseAuth
    //     .instance.currentUser!.uid).set({
    //   'userName': FirebaseAuth.instance.currentUser!.displayName,
    //   // ... and so on
    // });
    
  }

  @override
  Widget build(BuildContext context) {
    // Build your splash screen here
    return const Placeholder();
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.