This content originally appeared on Level Up Coding - Medium and was authored by Daria Orlova

whoami
So, a quick intro in case you haven’t read my posts before. My name is Daria, and I’m a Flutter developer at a mobile studio Chili Labs. Our main specialty is customer projects, and I’m currently working on one of them and supervising a couple of others.
What is this about?
In this series, I talk about my daily work as a Flutter developer, as well as tap into my evening pet projects. Basically an overview of the challenges, problems, interesting tasks, and just thoughts that I encounter during the week. And a small disclaimer: this is not a tutorial, in case I talk about any solutions, they are just my own takes on the issues, and you can come up with different ones. So with that in mind, let’s dive in 🤿
#Technical
If last week I was Daria the Migrations Queen, this week I played the role of Daria the Bug Slayer 😂 Any ideas who I might be next week? 😁
1. Slow API requests
My week started with a (legit) complaint from the client, that the initial app loading (cold start launching) seemed slow and a question whether we could do anything about it. Tbh, that issue was on my mind before, we’ve discussed this with QA, but never really got to investigate.
My initial thought was that maybe something is slow on the BE side (of course this would be my initial thought and not that something was wrong on my side, pfft 😂), but Postman quickly proved me wrong 😬 Then I started looking into our HTTP client library (which is dio by the way) and pinging my co-worker whether he had any problems with it because I remembered he mentioned something recently in chat.
He suggested I remove the recommended transformer, that parsed responses on the background via compute function, which is a wrapper for spawning isolates. And... the loading time decreased in 2-3 times! This is probably related to the fact that we had multiple consecutive API calls and an isolate was spawned for each of them. This was actually tested on Flutter 2.8, which reminded me that they promised performance gains automatically after upgrading to Flutter 2.8 for the compute function, but so far I haven’t noticed it 🤔 Maybe I should dig deeper into this 🤪
Also, a small tip pointed out by my co-worker, which might be obvious, but was still missed in some places in the code: if you have independent requests, it’s better to call them in parallel than awaiting each one consecutively, e.g.
final future1 = getListOfStuff1()
final future2 = getListOfStuff2()
final listOfStuff1 = await future1
final listOfStuff2 = await future2
2. App stuck on launch with a white screen
The title already sounds like a nightmare, right? 😂 Recently we started getting reports from some users, that something happened to the app, and now it only shows a white screen. One of them wrote that clearing the cache helped. Users were only on Android, but on different versions of the OS & the app & different devices. In Crashlytics I found some reports, that led me to a couple of flutter_secure_storage related threads (one of them).
This does seem like our issue because we do read on the app launch to determine whether the user is logged in and PlatformException would result in a “white screen”, but we still couldn’t reproduce it ourselves.
What more, is that we already had the proposed fix (disabled Android auto-backup) a long time ago, but the issue still occurred. Unfortunately, we had to fall back to the good ol’ try & catch for the secure storage operations 😅 This “fix” is not yet live, so I can’t be sure if it is that issue, but we’ll see next week 🙈
3. Force logout the user on invalid token response
Now, enough with the bugs 😂 There were a couple of more gems that I found in Crashlytics, but nothing really worth discussing.
But I had another interesting task. I’ve recently bumped into an issue when our staging BE was having some problems. It turned out that we weren’t handling force logout when any of the API requests (except refresh token) returned 401. So our algorithm was the following:
- getToken from SessionRepository in order to perform an API request
- In getToken we check if the current token expiresAt is expired
- If it is, we try to refresh the token. If it fails, we force logout the user.
- If it’s successful or expiresAt is not yet expired, we just return the current token.
- So the issue was at the part when expiresAt is not yet expired, but for whatever reason, the token is already invalid on BE. Then any API call with an invalid token returned 401, and the user was stuck in the app.
It’s a very rare case because our token is very short-lived and usually if anything failed, it would be during refresh. But it’s still a valid case, and it should be resolved.
Now, the most obvious, simple, and probably typically right solution, would be just hooking up an interceptor to the HTTP client library and force logging out the user when it catches 401 in the onError. And that was my initial thought, but the problem was that when we log out the user, we need to clean up after him (cache, data, etc.). In our case, that is the responsibility of SessionRepository, but SessionRepository itself requires an API client, which requires the dio instance. Hence, we can’t provide a SessionRepository instance to dio due to cyclic dependency. So I came up with a method, that handles the case, still encapsulates session-related logic in the SessionRepository and doesn’t at all depend on the HTTP library.
@override
Future<T> withToken<T>(Future<T> Function(String token) action) async {
// note for readers: getToken() also handles the refresh in case of expired token
final token = await getToken();
try {
final result = await action(token);
return result;
} catch (ex, st) {
if (ex is ApiException && ex.statusCode == 401) {
Fimber.w('Invalid token exception', ex: ex, stacktrace: st);
await clearData();
throw const NotSignedInException();
} else {
rethrow;
}
}
}
And then I can use it like that:
sessionRepository.withToken((token) {
apiClient.doSomethingWithToken(token);
});
And in case you’re wondering, there’s a bit more code under the hood (which is out of the scope of this post) that handles the not signed in status on the app level.
#2 Community
Are you still here? Did I not bore you to death yet? 😂
So I have a couple of updates in the community section too 😛
1. Mentorship in RigaTechGirls
First, I’m very excited to be a mentor in the RigaTechGirls mentorship program! This year I will have two mentees, and we will be learning Flutter. This is my first time being a Flutter mentor outside my job, so it’s even more interesting 😁 The program's duration is 6 months, starting from January 2022 and the goal of the program is to support women on their journey in the IT world 🙂
2. State management and app architecture
These topics are always pretty hot, but this week they were once again on the radar due to Android releasing a new guide for the app architecture. Besides discussing the actual guidelines, I’ve seen quite some people arguing that app architecture is overengineering in its notion because most of the apps are so small & are basically “JSON-parsers with colorful buttons”, that they don’t require any architecture.
As a developer working on multiple customer projects over the last years, I don’t agree with this opinion, because from my experience, a common and well-defined app architecture, besides all the obvious benefits (such as scalability, testability, code quality, etc.), has one more important benefit, and that is predictability. It allows plugging other developers in and out seamlessly on our projects, and this makes teams and development much more productive. I’ve discussed this in a thread on Twitter too 😉
By the way, I’ve recently listened to two great talks on state management and app architecture, so I can recommend them too:
- “Architectural thinking on Flutter State Management” by Majid Hajian
- “Flutter Architecture Components” by Alessio Salvadorini
3. Flutter Apprentice
One last thing that I wanted to mention in this section, is the Flutter Apprentice book, which is free until January 6th (which is not that far away!), so if you haven’t yet checked it out, do it while you can. I really liked the content and also the Ray Wenderlich format!
#3 Personal
I don’t have many updates in this section, because this week’s pet project was not any of my apps, but me being a Santa Claus and buying gifts for my family 😁 At this very moment of writing, I’m on the train to my hometown (for a weekend), where my parents and my brothers live and I have a huuge bag of toys, which is the result of this week's “pet project” 😂
But I did manage to work on Bunny Search v 1.1. on Sunday

In version 1.1 there will be a couple of changes:
- The app will be available in Russian. I’ve already translated it, that was the easy part 😂 For localizations we usually use the EasyLocalization package at work, so I used it in Bunny too. Cause it’s easy 😁
- A couple of bug fixes, that I overlooked trying to push the release 1.0 as soon as possible 😅
- And the biggest feature is the fuzzy search. Currently, it’s the easiest contains search, which isn’t perfect, because you don’t always know how to spell the brand name correctly, or maybe it has some diacritics. So for example, if you search dave, the search should still return Dove in the results (which it currently doesn’t).
On one of my work projects, I had to implement the Levenshtein distance algorithm for the same cause.
Informally, the Levenshtein distance between two words is the minimum number of single-character edits (insertions, deletions or substitutions) required to change one word into the other. It is named after the Soviet mathematician Vladimir Levenshtein, who considered this distance in 1965. © Wikipedia
But the dataset in that app was quite small, so it worked fast enough. That was not the case with Bunny, because there are thousands of brands to iterate through. I’ve tried 😁 So this is my personal “advent of code” for this year 😂 Have to come up with some complex solution & optimizations for this interesting task 🤪
Meanwhile, you can download Bunny Search v 1.0 🙂
Apple: https://apps.apple.com/us/app/bunny-search/id1592571643
Google: https://play.google.com/store/apps/details?id=lv.chi.bunny_search
And once again, thanks for reading, I hope you’ve found something interesting for yourself :) I’ll be happy to connect on Twitter (@dariadroid), and for your claps, comments, follows, and shares 🙂
Until (hopefully 😅) next week!
Daria 💙
Daria’s Flutter diaries #2 was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Level Up Coding - Medium and was authored by Daria Orlova

Daria Orlova | Sciencx (2021-12-29T23:01:00+00:00) Daria’s Flutter diaries #2. Retrieved from https://www.scien.cx/2021/12/29/darias-flutter-diaries-2/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.