flutter - 为什么在StreamBuilder的connectionState.done之后得到另一个connectionState类型?

标签 flutter dart

我创建了一个StreamController来处理身份验证。登录完成后,我订阅了一个用户。因此,我为此创建了一个类:

class AuthAPI {
  final FacebookLogin facebookLogin = FacebookLogin();
  final Dio _dio = Dio();
  final StreamController<User> _authStatusController = StreamController<User>.broadcast();

  Stream<User> get onAuthStatusChanged => _authStatusController.stream;

  // Facebook Sign In
  Future<User> facebookSignIn() async {
    FacebookLoginResult result = await facebookLogin.logIn(['public_profile', 'email']);
    switch(result.status) {
      case FacebookLoginStatus.loggedIn:
        return _sendFacebookUserDataToAPI(result);
      case FacebookLoginStatus.error:
        return null;
      case FacebookLoginStatus.cancelledByUser:
        print('Cancelled');
        return null;
      default:
        return null;
    }
  }

  // Sign Out
  void signOut() async {
    facebookLogin.logOut();
    _authStatusController.sink.add(null);
    _authStatusController.close();
  }

  Future<User> _sendFacebookUserDataToAPI(FacebookLoginResult result) async {
    final String facebookToken = result.accessToken.token;
    final Response graphResponse = await _dio.get(
        'https://graph.facebook.com/v4.0/me?fields='
            'first_name,last_name,email,picture.height(200)&access_token=$facebookToken');
    final profile = jsonDecode(graphResponse.data);

    ApiProvider apiProvider = ApiProvider();

    UserSocialAuth userSocialAuth = UserSocialAuth(
      firstName: profile['first_name'],
      lastName: profile['last_name'],
      email: profile['email'],
      provider: 'facebook',
      providerUserId: profile['id']
    );

    Map socialSignIn = await apiProvider.socialSignIn(userSocialAuth);
    User user;
    if (socialSignIn.containsKey('access_token')) {
      Map userData = await apiProvider.currentUser(socialSignIn['access_token']);
      user = User.fromJson(userData['data']);
      apiProvider.setAccessToken(socialSignIn['access_token']);
      _authStatusController.sink.add(user);
      print("Login Successful");
    } else {
      _authStatusController.sink.addError(socialSignIn['error']);
    }
    _authStatusController.close();
    return user;
  }
}

这是我的StreamBuilder:

return StreamBuilder(
      stream: userBloc.authStatus,
      builder: (BuildContext context, AsyncSnapshot snapshot) {
      print(snapshot.connectionState);
        switch(snapshot.connectionState) {
          case ConnectionState.active:
            User user = snapshot.data;
            if (user == null) {
              return SignInSignUpScreen();
            }
            return _showHomeUI(user, snapshot);
          case ConnectionState.done:
            User user = snapshot.data;
            if (user == null) {
              return SignInSignUpScreen();
            }
            print(user);
            return _showHomeUI(user, snapshot);
          default:
            return Center(child: CircularProgressIndicator());
        }
      }
    );

因此,当我进行登录时,它会显示一个CircularProgressIndicator,并且如果身份验证成功,则它必须显示主屏幕。但是,它仍然显示登录屏幕,当我打印connectionState的输出时,我看到connectionState.done之后,connectionState传递给connectionState.waiting,我不知道为什么。

这是控制台的输出:

并且当到达最后一个connectionState.done时,它没有数据。

最佳答案

您在_authStatusController.close();方法的末尾调用_sendFacebookUserDataToAPI –这意味着基础流已完成,并且流侦听器进入“完成”状态。

您应该改为创建例如dispose()类中的AuthAPI方法,然后在其中调用_authStatusController.close()。当不再需要AuthAPI时,应调用此方法。

关于flutter - 为什么在StreamBuilder的connectionState.done之后得到另一个connectionState类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58518264/

相关文章:

flutter - 是否有可能实现一个代表用户在 Flutter/Dart 中的通知数量的图标?

firebase - Flutter + Firebase:将应用程序配置为使用本地Firebase模拟器

flutter - 重新启动 CircularCountdownTimer flutter onComplete

asynchronous - 为 await block 中的对象字段分配新值进一步说明

flutter - 你怎么知道 DraggableScrollableSheet 是折叠还是展开

flutter - 对于哪些 flutter 小部件,我们需要使用 const?

Flutter TextField 正则表达式清除文本输入

android - Flutter build apk 有 bug 而 debug 很完美

dart - 使用Uint8List构造ByteData View 会在Chrome中引发异常

flutter - 如何从BLE制造商数据波动中获得所需值