Flutter初心者です。
Firebaseを使用して、
メールアドレスによる認証を実装しており、
認証に成功したユーザーのマイページ閲覧画面、編集画面を作成しております。
FirebaseからユーザーIDの情報を取ってくるのに、
下記のApiを作成しました。
dart
1「AuthApi.dart」 2 3class AuthApi { 4 5 //connect Firebase 6 final FirebaseAuth _auth = FirebaseAuth.instance; 7 8 //create user obj based on FirebaseUser 9 User _userFromFirebaseUser(FirebaseUser user) { 10 return user != null ? User(uid: user.uid) : null; 11 } 12 13 //auth change user stream 14 Stream<User> get user { 15 return _auth.onAuthStateChanged.map(_userFromFirebaseUser); 16 } 17}
そして、ChangeNotifierで上記のuserを下記のように取得しています。
dart
1「MypageNotification.dart」 2 3class MyPageNotification with ChangeNotifier { 4 //get user stream 5 Stream<User> user = AuthApi().user; 6}
また、上記ChangeNotifierをMaterialRouteの上部に設置し、どのウィジェットも読み取れるようにしています。
マイページ閲覧画面とマイページ編集画面で取ってきたユーザーIDを使用し、
ユーザーIDに基づいた情報(名前等)を表示、編集しようと思っています。
下記は、閲覧・表示画面の実装の一部です。
ユーザーIDをStreamBuilderで取ってきて、それをusersInfo(IDを渡してユーザーの情報を取得)の引数として渡しています。
dart
1StreamBuilder<User>( 2 stream: myPageNotification.user, 3 builder: (context, user) { 4 5 print(user); // 編集画面のみ「AsyncSnapshot<User>(ConnectionState.waiting, null, null)」が表示される 6 7 return user.data == null // 編集画面のみ常にnullとなる 8 ? Loading() 9 : StreamBuilder<List<UsersInfo>>( 10 stream: myPageNotification.usersInfo(user.data.uid), 11 builder: (context, usersInfo) { 12 return Container(
閲覧画面ではこの実装方法で情報が正しく表示されるものの、
編集画面では、上記の「return user.data」の部分でnullが返却され、
print(user)の部分で
「AsyncSnapshot<User>(ConnectionState.waiting, null, null)」という値が表示されます。
しかし、「MypageNotification.dart」を下記のようにuserを二つに分けて、
閲覧画面と編集画面で別々にユーザーIDを取ってくるとうまく値が取得できます。
dart
1「MypageNotification.dart」 2 3class MyPageNotification with ChangeNotifier { 4 //get user stream 5 Stream<User> userShow = AuthApi().user; 6 Stream<User> userEdit = AuthApi().user; 7}
上記方法で実装はできるのですが、なぜこのような現象になるのかわからず、ご教示いただければ幸いです。
また、Flutter初心者で実装方法が合っているか不確かで、マイページのようにユーザー情報を表示する画面ではどのようにChangeNotifierで値を渡しているのかご教示いただけると大変嬉しいです。
(ChangeNotifier以外でも良い方法があれば教えてください。。)
ご回答の程、よろしくお願いいたします!!
###追記 2020/02/22
ページの遷移にはNavigator.pushを使用し、
MaterialAppでルートを定義し、遷移しています。
void main() => runApp(MyApp());
dart
1class MyApp extends StatelessWidget { 2 3 Widget build(BuildContext context) { 4 return MultiProvider( 5 providers: [ 6 ChangeNotifierProvider<MainNotification>( 7 create: (_) => MainNotification()), 8 ChangeNotifierProvider<MyPageNotification>( 9 create: (_) => MyPageNotification()), 10 ], 11 child: const MaterialApp( 12 debugShowCheckedModeBanner: false, 13 initialRoute: '/', 14 onGenerateRoute: Router.generateRoute, 15 ), 16 ); 17 } 18}
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/02/22 08:26
2020/02/22 08:50 編集