如果我移动到另一个小部件,则无法使用"_auth.signOut()"



我试图建立一个应用程序与扑动firebase,我正面临着一个问题。在我完成任务的那一刻!用户登录后,他被发送到一个"家"。Widget,他可以在那里注销!然后我加了一个"抽屉"在"家里"小部件,我们可以在那里找到"首页"小部件或进入"refeições"小部件,如果我点击首页他去了"家"。小部件或者如果我点击"refeições"他去"refeições"小部件,然后点击主页他被送到了"家"部件,按钮"注销";不管用了!

这是我的代码:

主:

import 'package:flutter/material.dart';
import 'package:projeto_final/models/user.dart';
import 'package:projeto_final/screens/wrapper.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:projeto_final/services/auth.dart';
import 'package:provider/provider.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});

// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return StreamProvider<Userr?>.value(
initialData: null,
value: AuthServices().user, 
child: MaterialApp(
debugShowCheckedModeBanner: false,
home:
Wrapper(),
),
);
}
}

包装器:

import 'package:flutter/material.dart';
import 'package:projeto_final/models/user.dart';
import 'package:projeto_final/screens/authenticate/authenticate.dart';
import 'package:projeto_final/screens/home/home.dart';
import 'package:provider/provider.dart';
class Wrapper extends StatelessWidget {
const Wrapper({super.key});
@override
Widget build(BuildContext context) {
final user = Provider.of<Userr?>(context);
if (user == null) {
return Authenticate();
} else {
return Home();
}
}
}

:

import 'package:flutter/material.dart';
import 'package:projeto_final/models/user.dart';
import 'package:projeto_final/services/auth.dart';
import 'package:projeto_final/screens/home/refeicoes.dart';
import 'package:projeto_final/screens/home/navigatorDrawer.dart';
import 'package:provider/provider.dart';
class Home extends StatefulWidget {
const Home({super.key});
@override
State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
// instancia da auth
final AuthServices _auth = AuthServices();
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: const NavigationDrawer(),
backgroundColor: Colors.brown[50],
appBar: AppBar(
title: Text('Homre'),
backgroundColor: Colors.brown[400],
elevation: 0.0,
actions: <Widget>[
TextButton.icon(
style: TextButton.styleFrom(primary: Colors.black),
icon: Icon(
Icons.logout,
color: Colors.white,
),
label: Text(''),
onPressed: () async {
print("sigout"); // this apper on the Debug Cosole
await _auth.signout();
},
),
],
),
);
}
}

navigationDrawer:

import 'package:flutter/material.dart';
import 'package:projeto_final/models/user.dart';
import 'package:projeto_final/screens/home/home.dart';
import 'package:projeto_final/screens/home/perfil.dart';
import 'package:projeto_final/screens/home/refeicoes.dart';
import 'package:provider/provider.dart';
class NavigationDrawer extends StatelessWidget {
const NavigationDrawer({super.key});
@override
Widget build(BuildContext context) {
//final user = Provider.of<Userr?>(context);
return Drawer(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
buildHeader(context),
buildMenuItem(context),
],
),
),
);
}
// Infomações da pessoa
Widget buildHeader(BuildContext context) => Material(
color: Colors.blue.shade700,
child: InkWell(
onTap: () {
Navigator.pop(context);
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const Perfil(),
));
},
child: Container(
padding: EdgeInsets.only(
top: 24 + MediaQuery.of(context).padding.top,
bottom: 24,
),
child: Column(
children: <Widget>[
CircleAvatar(
radius: 52,
backgroundImage: NetworkImage(
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTpnpGpHRvo3bnHH-bUT_h5Y9Ao31CXetXjJMZ4HGcDasQ-oIc-VptCHRNzF3eeM5vOsQA&usqp=CAU'),
),
SizedBox(height: 12),
Text(
'base de dados',
style: TextStyle(fontSize: 28, color: Colors.white),
),
Text(
'base de dados@gmail.om',
style: TextStyle(fontSize: 16, color: Colors.white),
)
],
),
),
),
);
Widget buildMenuItem(BuildContext context) => Container(
padding: const EdgeInsets.all(24), // horizontal
child: Wrap(
runSpacing: 5, // vertical spacing
children: [
const Divider(color: Colors.black),
ListTile(
leading: const Icon(Icons.home_outlined),
title: const Text('Home'),
onTap: () {
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => Home(),
),
);
},
),
const Divider(color: Colors.black),
ListTile(
leading: const Icon(Icons.food_bank_outlined),
title: const Text('Refeições'),
onTap: () {
Navigator.pop(context);
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const Refeicoes(),
));
},
),
const Divider(color: Colors.black),
],
),
);
}

refeicoes:

import 'package:flutter/material.dart';
import 'package:projeto_final/screens/home/home.dart';
import 'package:projeto_final/screens/home/navigatorDrawer.dart';
class Refeicoes extends StatefulWidget {
const Refeicoes({super.key});
@override
State<Refeicoes> createState() => _RefeicoesState();
}
class _RefeicoesState extends State<Refeicoes> {
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: NavigationDrawer(),
appBar: AppBar(
title: Text('Refeições'),
),
);
}
}

身份验证:

import 'package:firebase_auth/firebase_auth.dart';
import 'package:projeto_final/models/user.dart';
class AuthServices {
// definir todos os metodos que vao comunicar com a firebase auth
final FirebaseAuth _auth = FirebaseAuth.instance;
// create a USER obj based on firebaseUser
Userr? _userFromFireBaseUser(User? user) {
//return Userr(uid: user.uid);
return user != null
? Userr(
uid: user.uid,
)
: null;
}
//auth change user stream
// função que devolve null ou entao o iud da pessoa que acabou de fazer regustar/sign
// função serve para ir para "home" ou entao para o "sign in"
Stream<Userr?> get user {
return _auth
.authStateChanges()
.map((User? user) => _userFromFireBaseUser(user));
//.map(_userFromFirebaseUser);
}
//sign in anon
Future signInAnon() async {
try {
UserCredential result = await _auth.signInAnonymously();
User? user = result.user;
return _userFromFireBaseUser(user);
} catch (e) {
print(e.toString());
return null;
}
}
// sign in with email and pass
Future SignInWithEmailPassword(String email, String password) async {
try {
UserCredential result = await _auth.signInWithEmailAndPassword(
email: email, password: password);
User? user = result.user;
return _userFromFireBaseUser(user);
} catch (e) {
print(e.toString());
return null;
}
}
// register with email and pass
Future registerWithEmailPassword(String email, String password) async {
try {
UserCredential result = await _auth.createUserWithEmailAndPassword(
email: email, password: password);
User? user = result.user;
return _userFromFireBaseUser(user);
} catch (e) {
print(e.toString());
return null;
}
}
//sign out
Future signout() async {
try {
return await _auth.signOut();
} catch (e) {
print(e.toString());
return null;
}
}
}

user.dart

class Userr {
final String uid;
Userr({required this.uid});
}

我试着放一个

print(user!.uid)

当我点击"signout"在调试控制台输入

════════ Exception caught by widgets library ═══════════════════════════════════
Null check operator used on a null value
The relevant error-causing widget was
Home
lib/…/home/navigatorDrawer.dart:76
════════════════════════════════════════════════════════════════════════════════ 

所以我认为问题是当我从一个小部件移动到另一个小部件时,我没有传递关于"用户"的数据

您可以尝试使用Firebase实例注销。

FirebaseAuth.instance.signOut();

这可能是由于堆叠。我会建议你创建一个全局AppBar,它可以在你想要调用它的每个屏幕上进行修改。这个方法需要创建一个自定义的应用程序栏statfulwidget。

我还注意到"FirebaseAuth.instance.signOut();"这些天。我建议的一种解决方法是使用共享首选项来存储用户ID并使用共享首选项验证ifLogin()。使用logOut()函数时,首先要删除共享首选项中的用户ID,然后导航回登录屏幕,而在同一个logOut()函数中,使用future delay将FirebaseAuth.instance.signOut()调用延迟几秒钟。

Future<void> signOut() async {
final prefs = await SharedPreferences.getInstance();
prefs.remove('userID');
Future.delayed(const Duration(seconds: 5), () => _auth.signOut());
}

也尝试在导航器的正确位置使用pushReplacement。这将减少你的屏幕堆栈层,并提供更好的性能。

最新更新