View profile

Flutter Fast, Flutter Far - Issue #2

Joseph Muller
Joseph Muller
Declarative Routing Makes it Easy

Take a simple mobile application, introduce the concept of users, and you now have a complicated mobile application. It might seem like a simple task at first thought but…think again. With users you will need to:
  • Structure your database to query by user ID
  • Manage users’ credentials
  • Check users’ permissions on database interactions
  • Verify users’ authentication statuses
  • Route users dynamically based on their authentication status
In this letter I’m going to dive into the last two points on this list. Each time a user opens your app, you need to determine what they should see.
  • If the user is new, they should see options to sign in or sign up.
  • If the user signed up but didn’t complete onboarding, they should be sent back to your onboarding workflow.
  • If a user is logged in and finished with onboarding, they should be sent to the home screen.
In each of these scenarios, we also need to prevent the user from accidentally seeing a screen that’s not meant for them (for example, we shouldn’t just “push” the user to the home screen if they are logged in because they might hit the back button and see the sign in/sign up screen again).
I’ve recently come up with a cool and intuitive way to handle this type of navigation using declarative navigation, a FirebaseAuth status listener, and a StreamViewModel from the stacked package.
Declarative Routing
To start, what is declarative programming and how can you implement it in your Flutter navigation scheme?
Declarative programming
The above article gives a great overview of this concept but in short, to declaratively program simply means to tell a computer what the end result of a computation or method should look like. You don’t necessarily tell the computer how to arrive at that outcome but instead let it do the work. From the article, declarative programming is like telling your taxi driver where you have to go. Imperative programming is like giving the taxi driver left/right directions on how to get to your destination.
Joe Muller
How do you prefer to navigate in #Flutter?
Building on this, declarative routing in Flutter means telling the system what routes should be in the navigation stack, much like you tell it what widgets should be included inside a Column. Imperative routing on the other hand, involves manually pushing those routes onto the navigation stack.
Auto Route and Navigator 2.0
In late 2020, the Flutter team introduced Navigator 2.0 with the hope that it would give developers more control over the navigation stack. With it, it became possible to push multiple pages onto the stack and remove pages at specific locations within the stack (ex. remove the third route down in the stack without popping the ones on top of it). This is declarative routing.
Although the developer response to this new way of doing things wasn’t all warm and fuzzy, the new navigation API is extremely useful in certain situations (queue our onboarding workflow) and with a navigation package like auto_route, we don’t have to worry about the technical details behind it. In fact, the auto_route package has a widget designed specifically to help you implement declarative routing.
So how does it work? I’m going to leave out the nitty, gritty details since this is a newsletter and highlight the important points. You can find the full code for this type of navigation inside the public repo for my new social media app, Fractio.
First, set up an AutoRoute called WelcomeView that will hold both a LoggedInView and a LoggedOutView.
Joe Muller
The AutoRouter that powers the above navigation scheme:
The idea here is to start all of your user’s navigation journeys inside the WelcomeView route. Note that the WelcomeView does not actually display any UI elements but is simply a wrapper for the two routes inside of it.
Using the AutoRouter.declarative constructor from the auto_route package, setup the WelcomeView like so:
Joe Muller
The cleanest solution I can come up with to handle varying user authentication statuses 🧼

Subscribe to my newsletter for more deets

#flutter #firebase #socialmedia #blogger

Created with @carbon_app
When using declarative routing, you should always order your routes in the order that the user is expected to encounter them. In the above example, we would typically expect a user to hit the LoggedOutView before they hit the LoggedInView so that’s why the two routes are arranged the way they are.
The last piece to the puzzle is updating the user’s navigation stack based on real-time changes to their authentication status. To do this, you can listen to the Firebase Auth state changes and rebuild the welcome view based on the output. In my app, I’m using the stacked state management package which comes with a StreamViewModel. Each time the user logs in or out, the WelcomeView rebuilds and the proper route is displayed. Easy!
Joe Muller
And the simple StreamViewModel that will rebuild the WelcomeView when the user's auth status changes:
Weekly Promo
I recently purchased an iPad Pro for sketching designs, creating logos, and using my Macbook with a second screen. As a standalone iPad, it’s pretty great but what really made me love it was this iPad stand by Logitech. The touchpad and keyboard makes browsing insanely fast and the cover is professional looking.
Did you enjoy this issue? Yes No
Joseph Muller
Joseph Muller @mullr33

The successful software development companies of the future will be the fastest.

Once a week, I'll dive into something related to coding efficiency, project management, or feature implementation.

In order to unsubscribe, click here.
If you were forwarded this newsletter and you like it, you can subscribe here.
Created with Revue by Twitter.