Firebase注销()问题(颤振)

Firebase注销()问题(颤振),firebase,flutter,firebase-authentication,Firebase,Flutter,Firebase Authentication,我有一个使用firebase的应用程序,我在RootPage中处理登录或登录,然后它会传递到我的第一页,如果我直接注销而没有从第一页转到任何路径,它工作正常,并将我引导到我的RootPage未签名版本,但是如果我从第一页转到任何路径,然后尝试注销它,请给出以下错误: D/FirebaseAuth(10720): Notifying id token listeners about a sign-out event. D/FirebaseAuth(10720): Notifying auth st

我有一个使用firebase的应用程序,我在RootPage中处理登录或登录,然后它会传递到我的第一页,如果我直接注销而没有从第一页转到任何路径,它工作正常,并将我引导到我的RootPage未签名版本,但是如果我从第一页转到任何路径,然后尝试注销它,请给出以下错误:

D/FirebaseAuth(10720): Notifying id token listeners about a sign-out event.
D/FirebaseAuth(10720): Notifying auth state listeners about a sign-out event.
I/flutter (10720): NoSuchMethodError: The method 'call' was called on null.
I/flutter (10720): Receiver: null
I/flutter (10720): Tried calling: call()
我有一个movetohome函数,可以从任何页面返回我的第一页,我认为它缺少了一些东西,我的函数如下

_moveToHome(BuildContext context) {
    Route route = MaterialPageRoute(builder: (context) => MyFirstPage(auth: FirebaseAuth.instance,userId: userId,));
    Navigator.push(context, route);
}
你可以在我的网页上找到firebase相关的部分

main.dart:

 void main() => runApp(new MyApp());

 class MyApp extends StatelessWidget {
      const MyApp();
      @override
      Widget build(BuildContext context) {
        return DynamicTheme(
            defaultBrightness: Brightness.light,
            data: (brightness) => ThemeData(
              pageTransitionsTheme: PageTransitionsTheme(
                  builders: {
                    TargetPlatform.android: CupertinoPageTransitionsBuilder(),
                    TargetPlatform.iOS: CupertinoPageTransitionsBuilder(),
                  }
              ),
              primarySwatch: Colors.blueGrey,
              accentColor: Colors.blueGrey,
              fontFamily: 'AvenirNext',
              brightness: brightness,
            ),

            themedWidgetBuilder: (context, theme) {
              return MaterialApp(
                theme: theme,
                home: new RootPage(auth: new Auth()),
                routes: <String, WidgetBuilder>{
                  MyFirstPage.routeName: (context) => new MyFirstPage(auth: new Auth()),
                  DetailPage.routeName: (context) => new DetailPage(auth: new Auth()),
                  GenrePage.routeName: (context) => new GenrePage(auth: new Auth())
                },
              );
            });
      }
    }
void main()=>runApp(新的MyApp());
类MyApp扩展了无状态小部件{
常量MyApp();
@凌驾
小部件构建(构建上下文){
返回动态模式(
defaultBrightness:Brightness.light,
数据:(亮度)=>主题数据(
pageTransitionsTheme:pageTransitionsTheme(
建筑商:{
TargetPlatform.android:CupertinoPageTransitionsBuilder(),
TargetPlatform.iOS:CupertinoPageTransitionsBuilder(),
}
),
原始样本:颜色。蓝灰色,
颜色:颜色。蓝灰色,
fontFamily:“AvenirNext”,
亮度:亮度,
),
主题WidgetBuilder:(上下文,主题){
返回材料PP(
主题:主题,,
主页:新建根页面(auth:new auth()),
路线:{
MyFirstPage.routeName:(上下文)=>新建MyFirstPage(auth:new auth()),
DetailPage.routeName:(上下文)=>new DetailPage(auth:new auth()),
GenrePage.routeName:(上下文)=>新的GenrePage(auth:new auth())
},
);
});
}
}
根页面:

import 'package:flutter/material.dart';
import 'package:randommoviefinal/screens/login_singup_page.dart';
import 'package:randommoviefinal/services/authentication.dart';
import 'package:randommoviefinal/screens/HomePage.dart';

enum AuthStatus {
  NOT_DETERMINED,
  NOT_LOGGED_IN,
  LOGGED_IN,
}

class RootPage extends StatefulWidget {
  RootPage({this.auth});

  final BaseAuth auth;

  @override
  State<StatefulWidget> createState() => new _RootPageState();
}

class _RootPageState extends State<RootPage> {
  AuthStatus authStatus = AuthStatus.NOT_DETERMINED;
  String _userId = "";

  @override
  void initState() {
    super.initState();
    widget.auth.getCurrentUser().then((user) {
      setState(() {
        if (user != null) {
          _userId = user?.uid;
        }
        authStatus =
        user?.uid == null ? AuthStatus.NOT_LOGGED_IN : AuthStatus.LOGGED_IN;
      });
    });
  }

  void loginCallback() {
    widget.auth.getCurrentUser().then((user) {
      setState(() {
        _userId = user.uid.toString();
      });
    });
    setState(() {
      authStatus = AuthStatus.LOGGED_IN;
    });
  }

  void logoutCallback() {
    setState(() {
      authStatus = AuthStatus.NOT_LOGGED_IN;
      _userId = "";
    });
  }

  Widget buildWaitingScreen() {
    return Scaffold(
      body: Container(
        alignment: Alignment.center,
        child: CircularProgressIndicator(),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    switch (authStatus) {
      case AuthStatus.NOT_DETERMINED:
        return buildWaitingScreen();
        break;
      case AuthStatus.NOT_LOGGED_IN:
        return new LoginSignupPage(
          auth: widget.auth,
          loginCallback: loginCallback,
        );
        break;
      case AuthStatus.LOGGED_IN:
        if (_userId.length > 0 && _userId != null) {
          return new MyFirstPage(
            userId: _userId,
            auth: widget.auth,
            logoutCallback: logoutCallback,
          );
        } else
          return buildWaitingScreen();
        break;
      default:
        return buildWaitingScreen();
    }
  }
}
导入“包装:颤振/材料.省道”;
导入“package:randommoviefinal/screens/login_singup_page.dart”;
导入“package:randommoviefinal/services/authentication.dart”;
导入“package:randommoviefinal/screens/HomePage.dart”;
枚举身份验证状态{
没有决心,
没有登录,
登录,
}
类RootPage扩展了StatefulWidget{
RootPage({this.auth});
最终BaseAuth-auth;
@凌驾
State createState()=>new_RootPageState();
}
类_RootPageState扩展了状态{
AuthStatus AuthStatus=未确定AuthStatus;
字符串_userId=“”;
@凌驾
void initState(){
super.initState();
widget.auth.getCurrentUser().then((用户){
设置状态(){
如果(用户!=null){
_userId=user?.uid;
}
身份=
user?.uid==null?AuthStatus.NOT_LOGGED_IN:AuthStatus.LOGGED_IN;
});
});
}
void loginCallback(){
widget.auth.getCurrentUser().then((用户){
设置状态(){
_userId=user.uid.toString();
});
});
设置状态(){
authStatus=authStatus.LOGGED\u登录;
});
}
void logoutCallback(){
设置状态(){
authStatus=authStatus.NOT\u LOGGED\u IN;
_userId=“”;
});
}
Widget BuildingWaitingScreen(){
返回脚手架(
主体:容器(
对齐:对齐.center,
子对象:CircularProgressIndicator(),
),
);
}
@凌驾
小部件构建(构建上下文){
交换机(身份验证状态){
案例身份。未确定:
返回BuildingWaitingScreen();
打破
案例身份验证状态。未登录:
返回新的LoginSignupPage(
auth:widget.auth,
loginCallback:loginCallback,
);
打破
案例AuthStatus.LOGGED\u登录:
如果(_userId.length>0&&u userId!=null){
返回新的MyFirstPage(
userId:\u userId,
auth:widget.auth,
logoutCallback:logoutCallback,
);
}否则
返回BuildingWaitingScreen();
打破
违约:
返回BuildingWaitingScreen();
}
}
}
我的首页:

class MyFirstPage extends StatefulWidget {
  MyFirstPage({Key key, this.auth, this.userId, this.logoutCallback})
      : super(key: key);

  final auth;
  final VoidCallback logoutCallback;
  final String userId;

  static String routeName = "/MyFirstPage";

  @override
  _MyFirstPageState createState() => new _MyFirstPageState();
}

class _MyFirstPageState extends State<MyFirstPage> {

  String userId;
  List<Movies> _moviesList;

  final FirebaseDatabase _database = FirebaseDatabase.instance;
  final GlobalKey<FormState> formKey = GlobalKey<FormState>();
  Query _moviesQuery;
  StreamSubscription<Event> _onMoviesAddedSubscription;
  StreamSubscription<Event> _onMoviesChangedSubscription;

 @override
  void initState() {
    // TODO: implement initState
    super.initState();

    _moviesList = new List();
    _moviesQuery = _database
        .reference()
        .child("movies")
        .orderByChild("userId")
        .equalTo(widget.userId);
    _onMoviesAddedSubscription = _moviesQuery.onChildAdded.listen(onEntryAdded);
    _onMoviesChangedSubscription =
        _moviesQuery.onChildChanged.listen(onEntryChanged);

  }

  void dispose() {
    _onMoviesAddedSubscription.cancel();
    _onMoviesChangedSubscription.cancel();
    super.dispose();
  }

  onEntryChanged(Event event) {
    var oldEntry = _moviesList.singleWhere((entry) {
      return entry.key == event.snapshot.key;
    });

    setState(() {
      _moviesList[_moviesList.indexOf(oldEntry)] =
          Movies.fromSnapshot(event.snapshot);
    });
  }

  onEntryAdded(Event event) {
    setState(() {
      _moviesList.add(Movies.fromSnapshot(event.snapshot));
    });
  }

  signOut() async {
    try {
      await widget.auth.signOut();
      widget.logoutCallback();
    } catch (e) {
      print(e);
    }
  }

  updateMovies(Movies movies) {
    //Toggle completed
    movies.watched = !movies.watched;
    if (movies != null) {
      _database.reference().child("movies").child(movies.key).set(movies.toJson());
    }
  }

  deleteMovies(String moviesId, int index) {
    _database.reference().child("movies").child(moviesId).remove().then((_) {
      print("Delete $moviesId successful");
      setState(() {
        _moviesList.removeAt(index);
      });
    });
  }
类MyFirstPage扩展StatefulWidget{
MyFirstPage({Key Key,this.auth,this.userId,this.logoutCallback})
:super(key:key);
最终授权;
最终作废回拨注销回拨;
最终字符串用户标识;
静态字符串routeName=“/MyFirstPage”;
@凌驾
_MyFirstPageState createState()=>new_MyFirstPageState();
}
类_MyFirstPageState扩展状态{
字符串用户标识;
列表(电影列表),;
final FirebaseDatabase _database=FirebaseDatabase.instance;
最终GlobalKey formKey=GlobalKey();
查询-电影查询;
流式订阅-移动附加订阅;
StreamSubscription _onMovieChangedSubscription;
@凌驾
void initState(){
//TODO:实现initState
super.initState();
_moviesList=新列表();
_moviesQuery=\u数据库
.reference()
.儿童(“电影”)
.orderByChild(“用户ID”)
.equalTo(widget.userId);
_onMoviesAddedSubscription=\u moviesQuery.onChildAdded.listen(onEntryAdded);
_OnMovieChangedSubscription=
_moviesQuery.onChildChanged.listen(onEntryChanged);
}
无效处置(){
_onMoviesAddedSubscription.cancel();
_onMovieChangedSubscription.cancel();
super.dispose();
}
onEntryChanged(事件){
var oldEntry=_moviesList.singleWhere((条目){
return entry.key==event.snapshot.key;
});
设置状态(){
_电影列表[_moviesList.indexOf(旧条目)]=
Movies.fromSnapshot(event.snapshot);
});
}
onEntryAdded(事件){
设置状态(){
_添加(Movies.fromsapshot(event.snapshot));
});
}
signOut()异步{
试一试{
等待widget.auth.signOut();
logoutCallback();
}捕获(e){
印刷品(e);
}
}
更新视频(电影){
//切换完成
movies.waved=!movies.waved;
如果(电影!=null){
_database.reference().child(“movies”).child(movies.key).set(movies.toJson());
}
}
deleteMovies(字符串moviesId,int索引)
class DetailPage extends StatefulWidget {
  MovieDetailPage({Key key, this.title, this.auth, this.userId})
      : super(key: key);

  final auth;
  final String userId;
  static String routeName = "/MyHomePage";
  final String title;

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

class _DetailPageState extends State<MovieDetailPage> {

  String userId;
  final FirebaseDatabase _database = FirebaseDatabase.instance;
  final GlobalKey<FormState> formKey = GlobalKey<FormState>();
  StreamSubscription<Event> _onMoviesAddedSubscription;
  StreamSubscription<Event> _onMoviesChangedSubscription;
  Query _moviesQuery;
  List<Movies> _moviesList;

  _moveToHome(BuildContext context) {
    Route route = MaterialPageRoute(builder: (context) => MyFirstPage(auth: FirebaseAuth.instance,userId: userId,));
    Navigator.push(context, route);}

@override
  void initState() {
    // TODO: implement initState
    super.initState();
    _moviesList = new List();
    _moviesQuery = _database
        .reference()
        .child("movies")
        .orderByChild("userId")
        .equalTo(widget.userId);
    _onMoviesAddedSubscription = _moviesQuery.onChildAdded.listen(onEntryAdded);
    _onMoviesChangedSubscription =
        _moviesQuery.onChildChanged.listen(onEntryChanged);
    widget.auth.getCurrentUser().then((user) {
      if (user != null) {
        userId = user?.uid;
      }});
  }

  void dispose() {
    _onMoviesAddedSubscription.cancel();
    _onMoviesChangedSubscription.cancel();
    super.dispose();
  }

  onEntryChanged(Event event) {
    var oldEntry = _moviesList.singleWhere((entry) {
      return entry.key == event.snapshot.key;
    });

    setState(() {
      _moviesList[_moviesList.indexOf(oldEntry)] =
          Movies.fromSnapshot(event.snapshot);
    });
  }

  onEntryAdded(Event event) {
    setState(() {
      _moviesList.add(Movies.fromSnapshot(event.snapshot));
    });
  }

  updateMovies(Movies movies) {
    //Toggle completed
    movies.watched = !movies.watched;
    if (movies != null) {
      _database.reference().child("movies").child(movies.key).set(movies.toJson());
    }
  }

  deleteMovies(String moviesId, int index) {
    _database.reference().child("movies").child(moviesId).remove().then((_) {
      print("Delete $moviesId successful");
      setState(() {
        _moviesList.removeAt(index);
      });
    });
  }

...
IconButton(
                            icon: Icon(Icons.home),
                            iconSize: 35,
                            onPressed: () {
                              _moveToHome(context);
                            },
                          ),

...

import 'dart:async';
import 'package:firebase_auth/firebase_auth.dart';

abstract class BaseAuth {
  Future<String> signIn(String email, String password);

  Future<String> signUp(String email, String password);

  Future<FirebaseUser> getCurrentUser();

  Future<void> sendEmailVerification();

  Future<void> signOut();

  Future<bool> isEmailVerified();
}

class Auth implements BaseAuth {
  final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;

  Future<String> signIn(String email, String password) async {
    AuthResult result = await _firebaseAuth.signInWithEmailAndPassword(
        email: email, password: password);
    FirebaseUser user = result.user;
    return user.uid;
  }

  Future<String> signUp(String email, String password) async {
    AuthResult result = await _firebaseAuth.createUserWithEmailAndPassword(
        email: email, password: password);
    FirebaseUser user = result.user;
    return user.uid;
  }

  Future<FirebaseUser> getCurrentUser() async {
    FirebaseUser user = await _firebaseAuth.currentUser();
    return user;
  }

  Future<void> signOut() async {
    return _firebaseAuth.signOut();
  }

  Future<void> sendEmailVerification() async {
    FirebaseUser user = await _firebaseAuth.currentUser();
    user.sendEmailVerification();
  }

  Future<bool> isEmailVerified() async {
    FirebaseUser user = await _firebaseAuth.currentUser();
    return user.isEmailVerified;
  }
}
 final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
class Auth implements BaseAuth {
 //Rest of class