简体   繁体   English

Flutter Provider 显示来自错误用户的数据

[英]Flutter Provider showing data from wrong user

In my application when I log in on 1 account (lets call him 'user1') and then logout of that user, then I log in on a second account ('user2'), my StreamProvider gets the correct UID from Firebase of the new user, but my StreamProviders below that use that 'uid' still show the data from the previous user.在我的应用程序中,当我登录 1 个帐户(让我们称他为“user1”)然后注销该用户,然后登录第二个帐户(“user2”)时,我的 StreamProvider 从 Firebase 获取正确的 UID 新用户,但我下面使用该 'uid' 的 StreamProviders 仍然显示来自前一个用户的数据。

This is an issue because in, for example, my StreamProvider<List> it gets the workouts from user1, and not from user2,... After HOT RESTARTING the app it will fix itself, but I need it to work without HOT Restarting这是一个问题,因为例如,在我的 StreamProvider<List> 中,它从 user1 获取锻炼,而不是从 user2,... HOT RESTARTING 应用程序后它会自行修复,但我需要它在没有 HOT Restarting 的情况下工作

So I guess my question is, either, "what am I doing wrong?"所以我想我的问题是,“我做错了什么?” or "how can I 'recreate' my StreamProviders (that use the UID) when the value of User/user.uid changes或“当 User/user.uid 的值更改时,我如何‘重新创建’我的 StreamProviders(使用 UID)

Thanks in advance提前致谢

This is the code in my main.dart, which contains all my Providers这是我的 main.dart 中的代码,其中包含我所有的 Providers

void main() {
  runApp(MyApp());
}



class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
      DeviceOrientation.portraitDown,
    ]);
    return MultiProvider(
      providers: [
        StreamProvider<User>(
          create: (_) => AuthService().user,
        ),
       
      ],
      child: Builder(
        builder: (BuildContext context) {
          final user = Provider.of<User>(context) ?? null;
         

          return MultiProvider(
            providers: [
              StreamProvider<List<Exercise>>(
                create: (_) => DatabaseService().exercises,
              ),
              StreamProvider<List<ExerciseCategory>>(
                create: (_) => DatabaseService().categories,
              ),
              StreamProvider<List<ExerciseEquipment>>(
                create: (_) => DatabaseService().equipment,
              ),
              StreamProvider<List<notification.Notification>>(
                create: (_) => DatabaseService().notifications,
              ),
              ChangeNotifierProvider<ExerciseFilter>(
                create: (_) => ExerciseFilter(),
              ),
              ChangeNotifierProvider<WorkoutChangeNotifier>(
                create: (_) => WorkoutChangeNotifier(),
              ),
              StreamProvider<List<UserExercise>>(
                create: (_) =>
                    DatabaseService(uid: user != null ? user.uid : '')
                        .userExercises,
              ),
              StreamProvider<List<WorkoutStreamProvider>>(
                create: (_) =>
                    DatabaseService(uid: user != null ? user.uid : '').workouts,
              ),
              StreamProvider<List<WorkoutHistory>>(
                create: (_) =>
                    DatabaseService(uid: user != null ? user.uid : '')
                        .workoutHistory,
              ),
              StreamProvider<UserSettings>(
                create: (_) =>
                    DatabaseService(uid: user != null ? user.uid : '').settings,
              ),
              StreamProvider<Nutrition>(
                create: (_) =>
                    DatabaseService(uid: user != null ? user.uid : '')
                        .nutrition,
              ),
            ],
            child: MaterialApp(
              theme: ThemeData(
                primarySwatch: Colors.grey,
                primaryTextTheme: TextTheme(
                  headline6: TextStyle(color: Colors.black, fontSize: 16.0),
                ),
                fontFamily: "Circular",
                backgroundColor: Colors.blueAccent,
              ),
              home: Wrapper(),
            ),
          );
        },
      ),
    );
  }
}

EDIT 1: get workouts code编辑 1:获取锻炼代码

List<WorkoutStreamProvider> _workoutStreamProviderListFromSnapshot(
    DocumentSnapshot snapshot,
  ) {
    //
    WorkoutExerciseSet _buildWorkoutExerciseSet(dynamic _set) {
      return WorkoutExerciseSet(
        reps: _set['reps'] ?? 0,
        weight: _set['weight'] ?? 0.0,
      );
    }

    List<WorkoutExerciseSet> _buildWorkoutExerciseSetList(dynamic sets) {
      List<WorkoutExerciseSet> setList = [];

      for (int i = 0; i < sets.length; i++) {
        setList.add(_buildWorkoutExerciseSet(sets[i]));
      }

      return setList;
    }

    WorkoutExercise _buildWorkoutExercise(dynamic exercise) {
      return WorkoutExercise(
        name: exercise['exerciseName'] ?? '',
        category: exercise['exerciseCategory'] ?? '',
        equipment: exercise['exerciseEquipment'] ?? '',
        restEnabled: exercise['restEnabled'] ?? true,
        restSeconds: exercise['restSeconds'] ?? 60,
        hasNotes: exercise['hasNotes'] ?? false,
        notes: exercise['notes'] ?? '',
        sets: _buildWorkoutExerciseSetList(exercise['sets']),
      );
    }

    List<WorkoutExercise> _buildWorkoutExerciseList(List<dynamic> exercises) {
      List<WorkoutExercise> workoutExerciseList = [];

      for (int i = 0; i < exercises.length; i++) {
        workoutExerciseList.add(
          _buildWorkoutExercise(exercises[i]),
        );
      }

      return workoutExerciseList;
    }

    WorkoutStreamProvider _buildWorkout(dynamic workout) {
      return WorkoutStreamProvider(
        id: workout['id'] ?? '',
        name: workout['workoutName'] ?? '',
        workoutNote: workout['workoutNote'] ?? '',
        exercises: _buildWorkoutExerciseList(workout['exercises']),
      );
    }

    List<WorkoutStreamProvider> workoutList = [];

    if (snapshot.exists && snapshot.data != null) {
      if (snapshot.data['workouts'] != null) {
        List<dynamic> workouts = snapshot.data['workouts'];

        for (int i = 0; i < workouts.length; i++) {
          workoutList.add(_buildWorkout(workouts[i]));
        }
      }
    }

    return workoutList;
  }

  Stream<List<WorkoutStreamProvider>> get workouts {
    print("GETTING WORKOUTS OF UID: " + uid);

    return userCollection
        .document(uid)
        .snapshots()
        .map(_workoutStreamProviderListFromSnapshot);
  }

UI用户界面

class WorkoutListWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final List<WorkoutStreamProvider> dbWorkouts =
        Provider.of<List<WorkoutStreamProvider>>(context) ?? [];

    final User user = Provider.of<User>(context) ?? null;

    final WorkoutChangeNotifier workout =
        Provider.of<WorkoutChangeNotifier>(context) ?? null;

    return ReorderableSliverList(
      delegate: ReorderableSliverChildListDelegate(
        [
          for (int i = 0; i < dbWorkouts.length; i++)
            Container(
              margin: EdgeInsets.all(16.0),
              child: InkWell(
                onTap: () {
                  workout.workoutStreamProviderToChangeNotifier(dbWorkouts[i]);
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (BuildContext context) => WorkoutViewPage(),
                    ),
                  );
                },
                child: Container(
                  padding: EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 8.0),
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(6.0),
                    border: Border.all(
                      color: Colors.grey[400],
                      width: 1,
                    ),
                  ),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: <Widget>[
                      Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: <Widget>[
                          Container(
                            padding: EdgeInsets.only(left: 16.0),
                            child: Text(
                              dbWorkouts[i].name,
                              style: TextStyle(
                                fontSize: 16.0,
                                fontWeight: FontWeight.w500,
                              ),
                            ),
                          ),
                          Theme(
                            data: Theme.of(context).copyWith(
                              cardColor: Color.fromRGBO(35, 35, 35, 1),
                              dividerColor: Color.fromRGBO(70, 70, 70, 1),
                            ),
                            child: PopupMenuButton(
                              offset: Offset(0, 50),
                              shape: RoundedRectangleBorder(
                                borderRadius:
                                    BorderRadius.all(Radius.circular(8.0)),
                              ),
                              icon: Icon(
                                Icons.more_vert,
                              ),
                              onSelected: (selection) async {
                                if (selection == 'edit') {
                                  print('EDIT WORKOUT');
                                  workout.workoutStreamProviderToChangeNotifier(
                                      dbWorkouts[i]);

                                  Navigator.push(
                                    context,
                                    MaterialPageRoute(
                                      builder: (BuildContext context) =>
                                          WorkoutEditPage(),
                                    ),
                                  );
                                } else if (selection == 'duplicate') {
                                  print('DUPLICATE WORKOUT');

                                  dynamic result = await DatabaseService(
                                    uid: user != null ? user.uid : '',
                                  ).duplicateWorkout(dbWorkouts[i], dbWorkouts);

                                  if (result != null) {
                                    print("Workout Duplicated");
                                  }
                                } else if (selection == 'delete') {
                                  dynamic result = await DatabaseService(
                                    uid: user != null ? user.uid : '',
                                  ).removeWorkout(dbWorkouts[i], dbWorkouts);

                                  if (result != null) {
                                    print("Workout Deleted");
                                  }
                                }
                              },
                              itemBuilder: (BuildContext context) =>
                                  <PopupMenuItem>[
                                PopupMenuItem(
                                  height: 40.0,
                                  value: 'edit',
                                  child: Text(
                                    'Edit workout',
                                    style: TextStyle(
                                      color: Colors.white,
                                      fontSize: 17.0,
                                    ),
                                  ),
                                ),
                                PopupMenuItem(
                                  height: 40.0,
                                  value: 'duplicate',
                                  child: Text(
                                    'Duplicate workout',
                                    style: TextStyle(
                                      color: Colors.white,
                                      fontSize: 17.0,
                                    ),
                                  ),
                                ),
                                PopupMenuItem(
                                  height: 40.0,
                                  value: 'delete',
                                  child: Text(
                                    'Delete workout',
                                    style: TextStyle(
                                      color: Colors.white,
                                      fontSize: 17.0,
                                    ),
                                  ),
                                ),
                              ],
                            ),
                          ),
                        ],
                      ),
                      for (int j = 0; j < dbWorkouts[i].exercises.length; j++)
                        Container(
                          padding: EdgeInsets.symmetric(
                              horizontal: 16.0, vertical: 2.0),
                          child: Text(dbWorkouts[i].exercises[j].equipment == ""
                              ? dbWorkouts[i]
                                      .exercises[j]
                                      .sets
                                      .length
                                      .toString() +
                                  ' x ' +
                                  dbWorkouts[i].exercises[j].name
                              : dbWorkouts[i]
                                      .exercises[j]
                                      .sets
                                      .length
                                      .toString() +
                                  ' x ' +
                                  dbWorkouts[i].exercises[j].name +
                                  " (" +
                                  dbWorkouts[i].exercises[j].equipment +
                                  ")"),
                        ),
                    ],
                  ),
                ),
              ),
            ),
        ],
      ),
      onReorder: (int oldIndex, int newIndex) {
        // Move Workout
        dynamic result = DatabaseService(
          uid: user != null ? user.uid : '',
        ).reorderWorkout(oldIndex, newIndex, dbWorkouts);
      },
    );
  }
}

I managed to fix my issue by placing an if around my Multiprovider inside the builder, and either returning my SignIn() screen if user doesn't exist and otherwise I return my multiprovider, containing the providers, and the Wrapper()我设法通过在构建器中的 Multiprovider 周围放置一个 if 来解决我的问题,如果用户不存在则返回我的 SignIn() 屏幕,否则我返回包含提供者的多提供者和 Wrapper()

This way I force my UI to rebuild on a change in my user provider and by forcing it to rebuild it has to recall my DatabaseService() functions with the new UID通过这种方式,我强制我的 UI 在我的用户提供程序的更改上重建,并通过强制它重建它必须使用新的 UID 调用我的 DatabaseService() 函数

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
      DeviceOrientation.portraitDown,
    ]);
    return MultiProvider(
      providers: [
        StreamProvider<User>(
          create: (_) => AuthService().user,
        ),
      ],
      child: Builder(
        builder: (BuildContext context) {
          final user = Provider.of<User>(context) ?? null;

          return user == null
              ? MaterialApp(
                  theme: ThemeData(
                    primarySwatch: Colors.grey,
                    primaryTextTheme: TextTheme(
                      headline6: TextStyle(color: Colors.black, fontSize: 16.0),
                    ),
                    fontFamily: "Circular",
                    backgroundColor: Colors.blueAccent,
                  ),
                  home: SignIn(),
                )
              : MultiProvider(
                  providers: [
                    StreamProvider<List<Exercise>>(
                      create: (_) => DatabaseService().exercises,
                    ),
                    StreamProvider<List<ExerciseCategory>>(
                      create: (_) => DatabaseService().categories,
                    ),
                    StreamProvider<List<ExerciseEquipment>>(
                      create: (_) => DatabaseService().equipment,
                    ),
                    StreamProvider<List<notification.Notification>>(
                      create: (_) => DatabaseService().notifications,
                    ),
                    ChangeNotifierProvider<ExerciseFilter>(
                      create: (_) => ExerciseFilter(),
                    ),
                    ChangeNotifierProvider<WorkoutChangeNotifier>(
                      create: (_) => WorkoutChangeNotifier(),
                    ),
                    StreamProvider<List<UserExercise>>(
                      create: (_) =>
                          DatabaseService(uid: user != null ? user.uid : '')
                              .userExercises,
                    ),
                    StreamProvider<List<WorkoutStreamProvider>>(
                        create: (_) =>
                            DatabaseService(uid: user != null ? user.uid : '')
                                .workouts),
                    StreamProvider<List<WorkoutHistory>>(
                      create: (_) =>
                          DatabaseService(uid: user != null ? user.uid : '')
                              .workoutHistory,
                    ),
                    StreamProvider<UserSettings>(
                      create: (_) =>
                          DatabaseService(uid: user != null ? user.uid : '')
                              .settings,
                    ),
                    StreamProvider<Nutrition>(
                      create: (_) =>
                          DatabaseService(uid: user != null ? user.uid : '')
                              .nutrition,
                    ),
                  ],
                  child: MaterialApp(
                    theme: ThemeData(
                      primarySwatch: Colors.grey,
                      primaryTextTheme: TextTheme(
                        headline6:
                            TextStyle(color: Colors.black, fontSize: 16.0),
                      ),
                      fontFamily: "Circular",
                      backgroundColor: Colors.blueAccent,
                    ),
                    home: Wrapper(),
                  ),
                );
        },
      ),
    );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何防止 firebase auth 更改用户提供程序 - flutter firebase - How to prevent from firebase auth to change user provider - flutter firebase 无法设置使用提供程序 Flutter 从 Firebase 数据库获取的数据 - Cannot set data fetched from Firebase Database using provider Flutter Flutter:提供者和 Firebase | 来自 Firestore 数据(映射)的 Object 列表从提供者返回 null - Flutter: Provider and Firebase | List of Object from Firestore Data (mapped) returns null from Provider authStateListener 出现故障,登录时显示错误的用户数据 - authStateListener acting buggy, showing wrong user data upon login Flutter - 使用提供商 package 监听 Firebase 用户的用户配置文件 (Firestore) 中的数据更改 - Flutter - Listening for data changes in user profile (Firestore) of Firebase user using provider package 使用提供者动态显示来自地图字符串的用户数据 - Display User Data From Map String Dynamic Using Provider 从 flutter 中的 firebase 检索特定用户数据 - Retrieve specific user data from firebase in flutter 如何从 firebase 向 flutter 中的用户发送数据? - How to send data from firebase to the user in flutter? 更新 firebase flutter 中用户的数据 - Update data from user in firebase flutter Flutter:从 Firebase 获取刷新用户数据 - Flutter: get user data on refresh from Firebase
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM