#flutter #get #flutter-getx
Вопрос:
У меня есть небольшое приложение flutter, которое использует аутентификацию Firebase для входа в систему, а затем использует bindStream для запроса списка документов из Firestore. Это работает с самого начала/горячего перезапуска, но как только я выхожу из системы, я получаю ошибку разрешения firebase/firestore, и последующие входы в систему не обновляют поток. Я думал, что a GetxController
удаляет потоки, созданные через bindStream
, когда удаляется представление, использующее контроллер. В этом случае, когда я выхожу из системы , я отключаю все маршруты через Get.offAll
, но, похоже, поток все еще активен, и именно тогда происходит ошибка разрешений. Но на самом деле я не совсем понимаю, что происходит.
главная.дротик
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
Get.put(LoginController());
Get.put(AuthController(), permanent: true);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
debugShowCheckedModeBanner: false,
title: 'GetX Firebase Firestore',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SplashScreen(),
);
}
}
auth_controller.dart
class AuthController extends GetxController {
final AuthService _authService = AuthService();
AuthService get authService => _authService;
final LoginController _loginController = Get.find<LoginController>();
LoginController get loginController => _loginController;
Rxn<User> _user = Rxn<User>();
User? get user => _user.value;
@override
void onReady() async {
// bind auth state to _firebaesUser, but also give an initial value
_user = Rxn<User>(_authService.currentUser);
_user.bindStream(_authService.authState);
//run every time auth state changes
ever<User?>(_user, handleAuthChanged);
super.onReady();
}
handleAuthChanged(User? user) {
print("handleAuthChanged - ${user?.uid}");
if (user == null) {
Get.offAll(() => LoginScreen());
} else {
Get.offAll(() => HomeScreen(), binding: HomeBinding());
}
}
}
user_controller.dart
class UserController extends GetxController {
final UserRepository _userRepository = UserRepository();
final repository = UserRepository();
final users = Rx<List<FirestoreUser>>([]);
late Rx<FirestoreUser> _firestoreUser;
FirestoreUser get firestoreUser => _firestoreUser.value;
@override
void onInit() {
super.onInit();
final user = FirebaseAuth.instance.currentUser;
if (user == null) return;
_firestoreUser = Rx<FirestoreUser>(FirestoreUser.fromAuth(user));
// get user data from firestore
_firestoreUser.bindStream(_userRepository.getUserById(user.uid));
// query user collection
getAllUsers();
}
void getAllUsers() {
users.bindStream(repository.getAllUsers());
}
}
home_screen.dart
class HomeScreen extends GetView<UserController> {
const HomeScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("All Sample Users"),
actions: [
IconButton(
onPressed: () => Get.to(ProfileScreen()),
icon: Icon(Icons.person),
),
],
),
body: Obx(
() => ListView.builder(
itemCount: controller.users.value.length,
itemBuilder: (context, index) {
final user = controller.users.value[index];
return ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(user.photoURL),
),
title: Text(user.displayName),
);
},
),
),
);
}
}
привязка к дому.дротик
class HomeBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut<UserController>(() => UserController(), fenix: true);
}
}