0

My app has a public area, and an area where users must be authenticated, for example a page with a chat. At the lowest level I have my authenticationService, where I can check if a user is authenticated by checking for null in:

authenticationService.currentUser

When I updated this functionality for null safety, I declared this variable as:

User? _currentUser;

However, within the chat-components I also often have to access the user, and since I know a user must already be authenticated to access this area I use "!" like this a lot:

authenticationService.currentUser!

Additionally I use assert on some entry-points to catch errors at least during development:

assert(authenticationService.currentUser != null);

Is there a better way than to use "!" a lot in these areas and basically disable the null safety here and hope for the best?

Christian
  • 558
  • 2
  • 13
  • 2
    If you know that variable never be null, then dont declare it as nullable. You can use `late` keyword: late User _currentUser; – Autocrab Sep 27 '21 at 12:04
  • But if the user is not authenticated it is null... – Christian Sep 27 '21 at 12:06
  • 1
    You can create subclass from user called AnonimousUser and assign it at start. User _currentUser = AnonimousUser(); Then later if user logs in you change it: _currentUser = User(); and change authenticationService.currentUser != null to authenticationService.currentUser is AnonimousUser or add isAnonimous() method to class – Autocrab Sep 27 '21 at 12:10

1 Answers1

3

I'd avoid direct access to the _currentUser variable, and instead go through two different getters:

User get currentUser => 
    _currentUser ?? (throw StateError("Not authenticated"));

bool get isAuthenticated => _currentUser != null;

That keeps the state logic local to a few methods, and it's now your own job to ensure you only read currentUser when you know it's authenticated. Which is no different from now, you just get a more readable error if you make a mistake than you get by !.

(Since your variable is called _currentUser and your code is doing .currentUser, you probably already have a getter wrapping the variable).

lrn
  • 64,680
  • 7
  • 105
  • 121
  • I like this, it's more explicit to call a named method instead of checking for null to see if user is authenticated, no more assertions when accessing the user, and an explicit error in case of an error. An you're right, I even got the getter already. – Christian Sep 28 '21 at 07:27