lohanidamodar / appwrite_auth_kit

Making Appwrite Authentication Easy
https://youtu.be/bqh8qjNCHno
MIT License
34 stars 14 forks source link

User redirected back to the login page after no internet connection #19

Open FaisalMohammadi opened 1 year ago

FaisalMohammadi commented 1 year ago

When their is no internet connection the state of the Auth changes to the unauthenticated and the user redirects to the login page After making the internet available back it goes directly to the main page and the auth state is then authenticated. It should stay authenticated or at least should stay in main page after no internet connection. from the UX perspective it looks not good that after no internet it redirects to the Login Page, but at the back its already authenticated.

My implementation of Auth

class MainWidget extends StatelessWidget {
  const MainWidget({super.key});

  @override
  Widget build(BuildContext context) {
    final authNotifier = context.authNotifier;
    Widget widget;
    switch (authNotifier.status) {
      case AuthStatus.authenticated:
        widget = const FeedPage();
        break;
      case AuthStatus.unauthenticated:
      case AuthStatus.authenticating:
        widget = const LoginPage();
        break;
      case AuthStatus.uninitialized:
        widget = const SplashScreenWidget();
        break;
      default:
        widget = const SplashScreenWidget();
        break;
    }
    return widget;
  }
}
FaisalMohammadi commented 1 year ago

any update to this?

FaisalMohammadi commented 1 year ago

is their anyone who can pick this issue and solve it. it would be great. Thank you

alterhuman commented 1 year ago

Were you able to solve this?

FaisalMohammadi commented 1 year ago

I forked the projekt and wanted to look into it but didnt found time for it. So no not solved yet. I am still waiting for that bug to be fixed actually.

alterhuman commented 1 year ago

@lohanidamodar can you have a look?

alterhuman commented 1 year ago

@FaisalMohammadi I fixed it. If you want to use it, here's the code:

// Save user locally
  Future<void> saveUserLocally(models.Account user) async {
    final prefs = await SharedPreferences.getInstance();
    String userJson = jsonEncode(user.toMap());
    prefs.setString('user', userJson);
  }

  // Get user locally
  Future<models.Account?> getUserLocally() async {
    final prefs = await SharedPreferences.getInstance();
    debugPrint('Getting user session from local storage');
    final userJson = prefs.getString('user');
    if (userJson != null) {
      Map<String, dynamic> userMap = jsonDecode(userJson);
      debugPrint(
          'User session found in local storage: ${models.Account.fromMap(userMap).name}');
      return models.Account.fromMap(userMap);
    }
    debugPrint('User session not found in local storage');
    return null;
  }

  // Remove user locally
  Future<void> removeUserLocally() async {
    debugPrint('Removing user session from local storage');
    final prefs = await SharedPreferences.getInstance();
    prefs.remove('user');
    debugPrint('Setting user id in constant to null');
    Constants.userId = null;
    debugPrint(
        'User session removed from local storage: ${prefs.getString('user')}');
  }

  // Then call these methods:
  Future _getUser({bool notify = true}) async {
    try {
      _user = await _account.get();
      if (_user != null) {
        debugPrint('Found active user session from server: ${_user!.name}');
        await saveUserLocally(_user!);
        _status = AuthStatus.authenticated;
      } else {
        _status = AuthStatus.unauthenticated;
      }
    } on AppwriteException catch (e) {
      debugPrint('Active user session not found on server');
      _user = await getUserLocally();
      _status =
          _user != null ? AuthStatus.authenticated : AuthStatus.unauthenticated;
      _error = e.message;
    } finally {
      _loading = false;
      if (notify) {
        notifyListeners();
      }
    }
  }

  Future<bool> deleteSession({String sessionId = 'current'}) async {
    try {
      await _account.deleteSession(sessionId: sessionId);
      await removeUserLocally();
      _user = null;
      _status = AuthStatus.unauthenticated;
      notifyListeners();
      return true;
    } on AppwriteException catch (e) {
      _error = e.message;
      return false;
    }
  }
FaisalMohammadi commented 1 year ago

where do i put these?

lohanidamodar commented 1 year ago

@FaisalMohammadi From UX perspective, it's okay to redirect back to login when no internet, even if they are logged in in the server, without internet the app shouldn't know about it. I feel it's better to notify with internet checking plugin and error message.

But if you want to make it work offline this is a good solution to your problem, but this might have other design issues which I'm not ready to tackle in this package. Want to keep this package simple. Also offline working is not in the scoope of this package.

Let me know what you think.