Flutter应用程序在日志屏幕中的无限加载

kmynzznz  于 2023-10-22  发布在  Flutter
关注(0)|答案(1)|浏览(133)

当我尝试从Flutter应用程序的登录屏幕输入电子邮件地址和密码登录时,无论我等待多久,我都无法登录该应用程序,它会无限加载。如何修复此错误?
下面是login.dart文件的代码:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:lifelink_ridersapp/authentication/auth_screen.dart';
import 'package:lifelink_ridersapp/global/global.dart';
import 'package:lifelink_ridersapp/mainScreens/home_screen.dart';
import 'package:lifelink_ridersapp/widgets/custom_text_field.dart';
import 'package:lifelink_ridersapp/widgets/error_dialog.dart';
import 'package:lifelink_ridersapp/widgets/loading_dialog.dart';

class LoginScreen extends StatefulWidget {
  const LoginScreen({Key? key}) : super(key: key);

  @override
  _LoginScreenState createState() => _LoginScreenState();
}


class _LoginScreenState extends State<LoginScreen>
{
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  TextEditingController emailController = TextEditingController();
  TextEditingController passwordController = TextEditingController();

  formValidation()
  {
    if(emailController.text.isNotEmpty && passwordController.text.isNotEmpty)
    {
      //login
      loginNow();
    }
    else
    {
      showDialog(
          context: context,
          builder: (c)
          {
            return ErrorDialog(
              message: "Please write email/password.",
            );
          }
      );
    }
  }

  loginNow() async
  {
    showDialog(
        context: context,
        builder: (c)
        {
          return LoadingDialog(
            message: "Checking Credentials",
          );
        }
    );

    User? currentUser;
    await firebaseAuth.signInWithEmailAndPassword(
      email: emailController.text.trim(),
      password: passwordController.text.trim(),
    ).then((auth){
      currentUser = auth.user!;
    }).catchError((error){
      Navigator.pop(context);
      showDialog(
          context: context,
          builder: (c)
          {
            return ErrorDialog(
              message: error.message.toString(),
            );
          }
      );
    });
    if(currentUser != null)
    {
      readDataAndSetDataLocally(currentUser!);
    }
  }

  Future readDataAndSetDataLocally(User currentUser) async
  {
    await FirebaseFirestore.instance.collection("riders")
        .doc(currentUser.uid)
        .get()
        .then((snapshot) async {
          if(snapshot.exists){
            await sharedPreferences!.setString("uid", currentUser.uid);
            await sharedPreferences!.setString("email", snapshot.data()!["riderEmail"]);
            await sharedPreferences!.setString("name", snapshot.data()!["riderName"]);
            await sharedPreferences!.setString("photoUrl", snapshot.data()!["riderAvatarUrl"]);

            Navigator.pop(context);
            Navigator.push(context, MaterialPageRoute(builder: (c)=> const HomeScreen()));
          }
          else{
            firebaseAuth.signOut();
            Navigator.pop(context);
            Navigator.push(context, MaterialPageRoute(builder: (c)=> const AuthScreen()));

            showDialog(
                context: context,
                builder: (c)
                {
                  return ErrorDialog(
                    message: "No Record Exists",
                  );
                }
            );
          }

    });
  }

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Column(
        mainAxisSize: MainAxisSize.max,
        children: [
          Container(
            alignment: Alignment.bottomCenter,
            child: Padding(
              padding: EdgeInsets.all(15),
              child: Image.asset(
                "images/signup.png",
                height: 270,
              ),
            ),
          ),
          Form(
            key: _formKey,
            child: Column(
              children: [
                CustomTextField(
                  data: Icons.email,
                  controller: emailController,
                  hintText: "Email",
                  isObsecre: false,
                ),
                CustomTextField(
                  data: Icons.lock,
                  controller: passwordController,
                  hintText: "Password",
                  isObsecre: true,
                ),
              ],
            ),
          ),
          ElevatedButton(
            child: const Text(
              "Login",
              style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold,),
            ),
            style: ElevatedButton.styleFrom(
              primary: Colors.orange,
              padding: const EdgeInsets.symmetric(horizontal: 50, vertical: 10),
            ),
            onPressed: ()
            {
              formValidation();
            },
          ),
          const SizedBox(height: 30,),
        ],
      ),
    );
  }
}

下面是Android Studio中控制台的屏幕截图:screenshot of console in Android Studio
我尝试输入电子邮件和密码并登录应用程序。但发生的事情是,应用程序的日志屏幕被无限加载。

h5qlskok

h5qlskok1#

正如错误所说,您正在对空值使用空检查运算符。
空检查运算符是“!“并且您正在使用它的readDataAndSetDataLocally函数。
这是可能失败的路线。

await sharedPreferences!.setString("email", snapshot.data()!["riderEmail"]);
await sharedPreferences!.setString("name", snapshot.data()!["riderName"]);
await sharedPreferences!.setString("photoUrl", snapshot.data()!["riderAvatarUrl"]);

在使用空检查运算符之前,必须确保这些值都不为空。
对于初学者来说,每次都使用空检查操作符是一种非常糟糕的做法。你可以在这里阅读更多关于如何避免这种情况的信息:
https://mario-gunawan.medium.com/4-ways-to-avoid-the-null-check-operator-on-flutter-e2b8e7d965d
考虑使用“?“操作符而不是sharedPreferences。这样,当sharedPreferences为null时,它就不会执行操作。
对于snapshot.data,你应该把它放在一个变量中,然后检查这个变量是否为null。如果不是,您可以将其添加到sharedPrefs

相关问题