主屏幕显示 firebaseAuth Flutter 中的空未来构建器

Posted

技术标签:

【中文标题】主屏幕显示 firebaseAuth Flutter 中的空未来构建器【英文标题】:Home screen showing null future builder in firebaseAuth Flutter 【发布时间】:2021-08-27 10:42:57 【问题描述】:

我目前正在尝试从 FirebaseAuth 获取当前用户状态,并在用户未注销时在主屏幕之间切换,如果用户已注销,则在启动屏幕之间切换。用户注册和登录都成功并在firestore数据库中注册。但是每次我从手机关闭应用程序并重新打开时,MediaQuery.of(context) 宽度都有一个空值并显示错误。

但底部导航栏仍在显示。当我重新构建应用程序并再次登录时它可以工作,它会将我带到主屏幕。仅当我关闭并重新打开应用程序时才会发生。

import 'package:country_code_picker/country_localizations.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'routes.dart';
import 'package:screens/home/home_screen.dart';
import 'package:screens/splash/splash_screen.dart';

import 'constants.dart';

Future<void> main() async 
  WidgetsFlutterBinding.ensureInitialized();
  runApp(MyApp());


class MyApp extends StatefulWidget 
  @override
  _MyAppState createState() => _MyAppState();


class _MyAppState extends State<MyApp> 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      supportedLocales: [Locale('en', 'US')],
      localizationsDelegates: [CountryLocalizations.delegate],
      title: 'App',
      theme: theme(),
      routes: routes,
      home: LandingPage(),
    );
  


class LandingPage extends StatelessWidget 
  const LandingPage(Key? key) : super(key: key);

  @override
  Widget build(BuildContext context) 
    final Future<FirebaseApp> _init = Firebase.initializeApp();
    return FutureBuilder(
      future: _init,
      builder: (context, snapshot) 
        if (snapshot.hasError) 
          return Scaffold(
            body: Center(
              child: Text("Error: $snapshot.error"),
            ),
          );
        

    if (snapshot.connectionState == ConnectionState.done) 
      return StreamBuilder(
        stream: FirebaseAuth.instance.authStateChanges(),
        builder: (context, streamSnapshot) 
          if (streamSnapshot.hasError) 
            return Scaffold(
              body: Center(
                child: Text("Error: $streamSnapshot.error"),
              ),
            );
          

          if (streamSnapshot.connectionState == ConnectionState.active) 
            print(streamSnapshot.data.toString());
            if (streamSnapshot.data == null) 
              return SplashScreen();
             else 
              return HomeScreen();
            
          

          return Scaffold(
            body: Center(
              child: CircularProgressIndicator(
                backgroundColor: Colors.white,
                color: kPrimaryColor,
                strokeWidth: 3,
              ),
            ),
          );
        ,
      );
    

    return Scaffold(
      body: Center(
        child: CircularProgressIndicator(
          backgroundColor: Colors.white,
          color: kPrimaryColor,
          strokeWidth: 3,
        ),
      ),
    );
  ,
);


也许我认为这是未来构建器或流构建器的问题?你们中的任何人都有解决此问题的方法或其他实现方法。

Launching lib/main.dart on STK L21 in debug mode...
✓  Built build/app/outputs/flutter-apk/app-debug.apk.
Connecting to VM Service at ws://127.0.0.1:33019/yIPGCqY2gwY=/ws
I/flutter ( 4249): locale.languageCode: en
D/AwareBitmapCacher( 4249): handleInit switch not opened pid=4249
I/flutter ( 4249): User(displayName: , email: rohanbhautoo@gmail.com, emailVerified: false, isAnonymous: false, metadata: UserMetadata(creationTime: 2021-06-10 08:20:44.583, lastSignInTime: 2021-06-10 15:50:23.573), phoneNumber: , photoURL: null, providerData, [UserInfo(displayName: , email: rohanbhautoo@gmail.com, phoneNumber: , photoURL: null, providerId: password, uid: rohanbhautoo@gmail.com)], refreshToken: , tenantId: null, uid: yviaYOJ5ziayFQhvhvemB3MjkPr1)

════════ Exception caught by widgets library ═══════════════════════════════════
The following _CastError was thrown building Body(dirty):
Null check operator used on a null value

The relevant error-causing widget was
Body
When the exception was thrown, this was the stack
#0      getProportionateScreenWidth
#1      Body.build
#2      StatelessElement.build
#3      ComponentElement.performRebuild
#4      Element.rebuild
...
════════════════════════════════════════════════════════════════════════════════

Size_config.dart

import 'package:flutter/material.dart';

class SizeConfig 
  static MediaQueryData? _mediaQueryData;
  static double? screenWidth;
  static double? screenHeight;
  static double? defaultSize;
  static Orientation? orientation;

  void init(BuildContext context) 
    _mediaQueryData = MediaQuery.of(context);
    screenWidth = _mediaQueryData!.size.width;
    screenHeight = _mediaQueryData!.size.height;
    orientation = _mediaQueryData!.orientation;
  


// Proportionate height per screen size
double getProportionateScreenHeight(double inputHeight) 
  double? screenHeight = SizeConfig.screenHeight;
  return (inputHeight / 812.0) * screenHeight!;


// Proportionate width per screen size
double getProportionateScreenWidth(double inputWidth) 
  double? screenWidth = SizeConfig.screenWidth;
  return (inputWidth / 375.0) * screenWidth!;

#0 的堆栈跟踪行是 return (inputWidth / 375.0) * screenWidth!;它显示我在 screenWidth 上使用空检查!。

【问题讨论】:

更多细节会有所帮助。你也有来自控制台的堆栈跟踪吗? @nilsmagnus 是的没问题,我已经添加了堆栈跟踪。 【参考方案1】:

我没有看到您实际调用 SizeConfig().init(context) 的位置? 在您的项目开始之前,什么都不会为您定义。

【讨论】:

非常感谢。我忘了在 LandingPage() 的构建中添加它。这就是 mediaQueryData 返回 null 的原因。【参考方案2】:

我猜罪魁祸首是这一行:

print(streamSnapshot.data.toString());

您实际上是在检查下一行的 streamSnapshot.data 是否为空:

            print(streamSnapshot.data.toString());
            if (streamSnapshot.data == null) 
              return SplashScreen();
             else 
              return HomeScreen();
            

【讨论】:

我已经编辑并添加了堆栈跟踪。实际上,打印显示了用户详细信息,但如果没有用户,它确实返回 null。仅当用户未注销并重新打开应用程序时才会发生这种情况。无法看到主屏幕。

以上是关于主屏幕显示 firebaseAuth Flutter 中的空未来构建器的主要内容,如果未能解决你的问题,请参考以下文章

如何在颤振中从 FirebaseAuth 电话验证方法返回变量?

在不使用 3rd 方库的情况下,在反应本机中显示主屏幕之前显示启动屏幕

恢复后有时会在 Nativescript-Vue 上显示主屏幕

如何在主屏幕和子屏幕中显示状态栏和隐藏状态栏

如何检查 iPhone 上是不是显示主屏幕?

应用小部件仅在主屏幕上显示为灰色