We’ve Deployed Flutter into Production: Here are the Challenges We Faced 🦅

Read about our journey on deploying and maintaining a Flutter application from build all the way to production

Sergi Castellsagué Millán
Stuart Tech
7 min readAug 29, 2019

--

If I had to draw a visual representation of my feelings around Flutter now that we have deployed our application to production, I think it would look something like a rollercoaster. Quite steep at the beginning, and a couple of big drops in between, ending with a steady flat line.

N.B. You can find my more about my initial feelings regarding Flutter in a previous article.

The hype

It makes complete sense. Something new. Something very promising. Just a couple lines of code and you have a Material-Design looking app!

A couple of days after starting to work with Flutter we were like…

  • Where are the XML/Storyboards?
  • Where are the Activities/Controllers?
  • Why can’t I edit a Widget?
  • Damn checkbox! Why isn’t it listening to my taps?!

Pretty soon we discovered that we would not make much use of our previous mobile development experience.

There were a lot of novelties: a new language, SDK, tools, IDE (for the iOS guys), patterns…

We love learning!

Something I tend to tell to everybody I speak with, regarding the mobile development world, is that we are learning every day because we are forced to. If you are not up to date with the latest changes from Google or Apple regarding Android/iOS programming, in just a few months you will be pretty lost and feel like you are doing something completely new. However, learning is not a concern for us, it’s actually quite the opposite.

On the one hand, learning to work with Flutter is incredibly exciting. On the other hand, there is an important downside of using Flutter professionally. You stop spending eight hours a day doing native Kotlin / Swift as well as playing around with Google’s / Apple’s APIs.

To give an example: recently Apple released SwiftUI but the iOS guys have not had time to try it out yet — however, if we were still working with the native approach, I’m sure we would be using it in production already. (edit on 5th of September 2019) It is true though, as pointed out by Tim Sneath that this is a specific feature which is only available for iOS 13, so you would also need to maintain pre-13 code for UI. This is another goal in favor of Flutter, it is not dependant on the OS version.

Learning Dart was quite straightforward, on one side we felt like going backwards — adding semicolons at the end of every line — but Futures and Streams are very powerful tools, easy to understand, even more for us that we are used with reactive programming with libraries like with RxJava/RxKotlin or RxSwift. We have all of this out of the box!

What they don’t tell you

So many things. It is very easy to find articles explaining how perfect Flutter is. Most of them are actually like that. I think that this might be because people have not yet shipped a big application to production using it.

Performance issues

It might be great with simple applications, but the moment you start building complex UIs, or even adding PlatformViews, it drops dramatically. It is possible that we are still learning and that we are doing something very wrong, but just try it out: Add a GoogleMaps Widget (which is a PlatformView behind the scenes…) and then a Drawer menu on top. Performance degradation (mainly on iOS) is already noticeable.

It is true, though, that after many trials and errors, some workarounds (even some pull requests…) things got slightly better. Which is encouraging! Flutter is still in its early stages, and you can feel it.

Saving instance state (Specially for Android)

It might not be an issue for iOS, but it is for Android. If you have ever developed for Android, I am sure you had to deal with it. There’s no way to recover the app from an activity restart in Flutter at all. You need to write it on your own. This is a no-go for a lot of people.

Good news for us is that our app is — UI wise — not very complicated, and everything happens on a single screen. Also, its state is quite simple as it is server-driven. We can recover it anytime with ease.

Long run executions

If you want to run Dart for long periods of time (again, mainly an Android issue) you’ll have troubles. I published an article on how to overcome this issue.

Permissions management, notifications, media playing…

Flutter does not handle these out of the box, as it needs interaction with the host operative system. So you either find a package that does that for you or you will have to code them on your own. There are plenty of plugins already developed, but all we found at the moment, were either somehow bugged or were missing features.

Be prepared to write several PlatformChannels in order to deal with these. You will need to communicate your Dart code with your Kotlin and Swift code asynchronously, looking for the perfect balance between native code and Dart code. Remember that Dart code should be as generic as possible, so you do not want to deal with Android/iOS peculiarities on the Dart side.

You are building a cross-platform application. If you add too many lines of code in Swift or Kotlin, you are doing it wrong!

Random crashes

As an Android developer, I was quite used to these random crashes. To be honest, I thought that with Flutter we would get rid of them all for good. Sadly, that was not the case.

An example of a crash that does not belong to our code

Instead, we see these errors not only on Android but also on iOS. According to Crashlytics, our crash-free sessions are above 98%.

However, too many users have experienced crashes. As we have a single codebase, we were expecting to have similar figures in both platforms, but the reality is that around 50% of iOS users experienced crashes and 30% of Android users experienced crashes.

Our two biggest crashes have been reported to the Flutter team, and they are aware of them, so we expect them to disappear soon.

The first one: If you touch the Google Maps view (on Android) with three fingers, the app crashes. Crazy huh? — https://github.com/flutter/flutter/issues/20517

The second one: No clue when / how it happens, seems to be related to Accessibility functionalities — https://github.com/flutter/flutter/issues/38063 (Update on the 27th of September: Fixed 💥)

Some other crashes are not reported to the Flutter team, but we can’t find a way to reproduce them. We guess those are caused by race conditions, and we also guess that improving performance should reduce these race conditions.

Google Maps

This was a real issue for us. Our app relies completely on maps. We had to write several pull requests to the Google Maps plugin for Flutter in order to make it usable for us. Which, at the end is good. This way we had a chance to give something back to the community!

Only debug version of the APP will run in Android Emulators

Google’s Android emulator is not an ARM emulator. It is x86 based. So Flutter, with its AOT compilation won’t run there. Luckily, when debugging, it does use a JIT compilation, so you can use it for development.

However, for your final build, the one you are uploading to Google Play — it will not run there. Crossing fingers that manufacturers keep using ARM CPUs and do not decide to switch back…

Provided widgets are not good enough

You would expect common Widgets like BottomSheet to work right away, and be easy to tune. This is not the case. We ended up creating it from scratch, but it took little effort, luckily. In this case, I have to admit that Flutter allows you to create widgets with ease.

SVGs do not work

We had this issue for a very long time in Android until Lollipop was released as being SVG compatible (mostly). Now that we were finally able to use them… Boom, Flutter does not get along with them.

Not easy to profile

I admit there is a chance that we just need more time to learn, but we can’t profile our app as we used to in iOS or Android.

In just a few months, the debugging and profiling tools (integrated with Android Studio) improved a lot. However, as we are still learning how does Flutter run behind the scenes, we still do not know what to expect to fix.

Conclusion

We really like Flutter, and we feel very comfortable with Dart now. We are a team of just 4 mobile developers (originally 2 android and 2 iOS) and we were able to “merge” the team in a way that we can pair program with each other; we halved our bugs and doubled the capacity to fix them!

To prove it, these are the lines of code of our app:

  • Total: 30118
  • Dart (*.dart): 27184 (~90,25%)
  • Kotlin (*.kt): 1996 (~6,62%)
  • Swift (*.swift): 938 (~3,11%)

Yet, we expect Flutter to improve a lot in the following months.

We think that before we embark on a new journey of recoding our Client Application, the Flutter dev team must tackle the following items:

  1. Google using it on their products. If they’re not using it massively already, there must be a reason, and I doubt it’s a political one. If it were a viable (or even a better) alternative, they would be using it everywhere. (Edit: See https://medium.com/@timsneath/we-are-hundreds-of-google-developers-are-writing-flutter-code-who-dont-work-for-the-flutter-team-a9c6f5d44086)
  2. It should handle Android’s Activity restarts in an elegant way. — This is our main concern with the Client Application.
  3. Google maps component should not be a Flutter plugin but a real Widget.

We’re planning a Flutter Meetup in our offices in Barcelona in October. Stay tuned.

Would you like to see more? We are hiring! 🚀 Check out our open positions.

--

--