首页 > 解决方案 > 登录或注册后,用户不会被定向到提要屏幕。(Flutter Firebase)

问题描述

根据我在包装器 (wrapper.dart) 中编写的代码,在用户登录后,应将用户引导至提要屏幕。

但是当我登录时它不起作用(我使用的注册电子邮件与我最初注册时存储在 Firebase 中的相同)。我不知道哪个部分使它出错。

这是代码目录和终端消息。

用户.dart

class UserModel {
  final String? id;
  UserModel({this.id});
}

认证飞镖

import 'package:firebase_auth/firebase_auth.dart';
import 'package:twitterclone/models/users.dart';

class AuthService {
  FirebaseAuth auth = FirebaseAuth.instance;

  UserModel? _userFromFirebaseUser(User? user) {
    return user != null ? UserModel(id: user.uid) : null;
  }

  Stream<UserModel?> get user {
    return auth.authStateChanges().map(_userFromFirebaseUser);
  }

  Future signUp(emailSignUp, passwordSignUp) async {
    try {
      User user = await auth.createUserWithEmailAndPassword(
          email: emailSignUp, password: passwordSignUp) as User;
      _userFromFirebaseUser(user);
    } on FirebaseAuthException catch (e) {
      if (e.code == 'weak-password') {
        print('The password provided is too weak.');
      } else if (e.code == 'email-already-in-use') {
        print('The account already exists for that email.');
      }
    } catch (e) {
      print(e);
    }
  }

  Future signIn(emailSignIn, passwordSignIn) async {
    try {
      User user = (await auth.signInWithEmailAndPassword(
          email: emailSignIn, password: passwordSignIn)) as User;

      _userFromFirebaseUser(user);
    } on FirebaseAuthException catch (e) {
      print(e);
    } catch (e) {
      print(e);
    }
  }

  Future signOut() async {
    try {
      return await auth.signOut();
    } catch (e) {
      print(e.toString());
      return null;
    }
  }
}

注册.dart

import 'package:flutter/material.dart';
import 'package:twitterclone/screens/auth/welcome.dart';
import 'package:twitterclone/services/auth/auth.dart';

class SignUp extends StatefulWidget {
  @override
  _SignUpState createState() => _SignUpState();
}

class _SignUpState extends State<SignUp> {
  String emailSignUp = '';
  String passwordSignUp = '';
  bool _passwordVisible = false;
  final AuthService _authService = AuthService();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
            color: Colors.black,
            icon: Icon(Icons.arrow_back_rounded),
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => Welcome()),
              );
            }),
        title: Image.asset(
          'assets/icons/invale_icon.png',
          height: 60,
        ),
        centerTitle: true,
        backgroundColor: Colors.white,
        elevation: 0,
      ),
      body: SingleChildScrollView(
        child: Container(
          padding: EdgeInsets.symmetric(horizontal: 20, vertical: 20),
          child: Form(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: <Widget>[
                Text(
                  'Create your account',
                  style: TextStyle(
                      color: Colors.black,
                      fontWeight: FontWeight.bold,
                      fontSize: 30),
                ),
                SizedBox(
                  height: 30,
                ),
                TextFormField(
                  decoration: InputDecoration(
                      labelText: 'Email', labelStyle: TextStyle(fontSize: 15)),
                  style: TextStyle(fontSize: 18),
                  onChanged: (val) => setState(() {
                    emailSignUp = val;
                  }),
                ),
                SizedBox(
                  height: 15,
                ),
                TextFormField(
                  decoration: InputDecoration(
                    labelText: 'Password',
                    labelStyle: TextStyle(fontSize: 15),
                    suffixIcon: IconButton(
                      icon: Icon(
                        _passwordVisible
                            ? Icons.visibility
                            : Icons.visibility_off,
                        color: Theme.of(context).primaryColorDark,
                      ),
                      onPressed: () {
                        setState(() {
                          _passwordVisible = !_passwordVisible;
                        });
                      },
                    ),
                  ),
                  style: TextStyle(fontSize: 18),
                  obscureText: _passwordVisible,
                  validator: (val) =>
                      val!.length < 6 ? 'Password too short.' : null,
                  onChanged: (val) => setState(() {
                    passwordSignUp = val;
                  }),
                ),
              ],
            ),
          ),
        ),
      ),
      bottomNavigationBar: BottomAppBar(
          child: Padding(
        padding: EdgeInsets.symmetric(horizontal: 8),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            MaterialButton(
              elevation: 0,
              child: Text(
                'Create account',
                style: TextStyle(
                    fontSize: 18,
                    fontWeight: FontWeight.bold,
                    color: Colors.white),
              ),
              color: Color(0xff4aa8e0),
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(20)),
              onPressed: () async =>
                  {_authService.signUp(emailSignUp, passwordSignUp)},
            ),
          ],
        ),
      )),
    );
  }
}

登录.dart

import 'package:flutter/material.dart';
import 'package:twitterclone/screens/auth/welcome.dart';
import 'package:twitterclone/services/auth/auth.dart';

class SignIn extends StatefulWidget {
  @override
  _SignInState createState() => _SignInState();
}

class _SignInState extends State<SignIn> {
  String emailSignIn = '';
  String passwordSignIn = '';
  bool _passwordVisible = false;
  final AuthService _authService = AuthService();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.white,
        elevation: 0,
        leading: IconButton(
            color: Colors.black,
            icon: Icon(Icons.arrow_back_rounded),
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => Welcome()),
              );
            }),
        title: Image.asset(
          'assets/icons/invale_icon.png',
          height: 60,
        ),
        centerTitle: true,
      ),
      body: SingleChildScrollView(
        child: Container(
          padding: EdgeInsets.symmetric(horizontal: 20, vertical: 20),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Text(
                'Log in to Invale.',
                style: TextStyle(
                    color: Colors.black,
                    fontSize: 25,
                    fontWeight: FontWeight.bold),
              ),
              SizedBox(
                height: 15,
              ),
              TextFormField(
                decoration: InputDecoration(
                    labelText: 'Email', labelStyle: TextStyle(fontSize: 15)),
                style: TextStyle(fontSize: 18),
                onChanged: (val) => setState(() {
                  emailSignIn = val;
                }),
              ),
              SizedBox(
                height: 20,
              ),
              TextFormField(
                decoration: InputDecoration(
                  labelText: 'Password',
                  labelStyle: TextStyle(fontSize: 15),
                  suffixIcon: IconButton(
                    icon: Icon(
                      _passwordVisible
                          ? Icons.visibility
                          : Icons.visibility_off,
                      color: Theme.of(context).primaryColorDark,
                    ),
                    onPressed: () {
                      setState(() {
                        _passwordVisible = !_passwordVisible;
                      });
                    },
                  ),
                ),
                obscureText: _passwordVisible,
                style: TextStyle(fontSize: 18),
                onChanged: (val) => setState(() {
                  passwordSignIn = val;
                }),
              ),
            ],
          ),
        ),
      ),
      bottomNavigationBar: BottomAppBar(
          child: Padding(
        padding: EdgeInsets.symmetric(horizontal: 8),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            MaterialButton(
              elevation: 0,
              child: Text(
                'Log in',
                style: TextStyle(
                    fontSize: 18,
                    fontWeight: FontWeight.bold,
                    color: Colors.white),
              ),
              color: Color(0xff4aa8e0),
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(20)),
              onPressed: () async =>
                  {_authService.signIn(emailSignIn, passwordSignIn)},
            ),
          ],
        ),
      )),
    );
  }
}

包装器.dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:twitterclone/models/users.dart';
import 'package:twitterclone/screens/auth/welcome.dart';
import 'package:twitterclone/screens/mainscreen/feedscreen.dart';

class Wrapper extends StatelessWidget {
  const Wrapper({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    final user = Provider.of<UserModel?>(context);
    print(user);
    if (user == null) {
      return Welcome();
    } else {
      return FeedScreen();
    }
  }
}

自应用程序启动以来的终端消息,直到我单击登录按钮

I/flutter ( 7705): null
W/IInputConnectionWrapper( 7705): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper( 7705): getSelectedText on inactive InputConnection
W/IInputConnectionWrapper( 7705): getTextAfterCursor on inactive InputConnection
W/IInputConnectionWrapper( 7705): beginBatchEdit on inactive InputConnection
W/IInputConnectionWrapper( 7705): endBatchEdit on inactive InputConnection
2
W/System  ( 7705): Ignoring header X-Firebase-Locale because its value was null.
D/FirebaseAuth( 7705): Notifying id token listeners about user ( Ggeh9OkrDvRXTPaC53hvBXhi4NA2 ).
D/FirebaseAuth( 7705): Notifying auth state listeners about user ( Ggeh9OkrDvRXTPaC53hvBXhi4NA2 ).
I/flutter ( 7705): type 'UserCredential' is not a subtype of type 'User' in type cast
I/flutter ( 7705): Instance of 'UserModel'

标签: androidfirebaseflutterdartfirebase-authentication

解决方案


推荐阅读