If you’ve used the Firebase Auth package before, you’ve probably noticed that macOS is listed as one of the supported platforms.
But as it turns out, getting even a very basic Flutter & Firebase app to run on macOS is a challenge, fraught with many perils. 😰
And to help you overcome all the hurdles, I’ve prepared this step-by-step guide.
Why this guide?
macOS is my target platform of choice when writing Flutter apps, for three reasons:
- it supports hot reload (just like iOS and Android)
- it doesn't use a ton of CPU/memory (I'm looking at you, Android Emulator)
- the window is resizable (making it easy to test responsive UIs)
But if you add Firebase to the mix and try to run your Flutter app on macOS, all sorts of errors show up, and you're likely to waste a few hours on StackOverflow just to get things working again.
To save you some time and frustration, I decided to write this guide and share my findings.
In sharing this, I also hope that the FlutterFire maintainers will take notice and make it easier for developers to work with Flutter & Firebase on macOS. To that effect, I shared some criticism and suggestions at the end.
How does this guide work?
To focus on the problem at hand, I’m sharing a simple Flutter & Firebase app that already contains a simple authentication flow and works as intended on all other platforms (iOS, Android, web):
But as we’ll see, we’ll encounter a series of errors if we try to run the same app on macOS.
You can find the source code for the whole app here:
Getting Started
If you want to get the sample app running, follow these initial steps:
- clone the GitHub repo and open it in VSCode
- create a new project in the Firebase console and follow all the steps to add a Flutter app
- run
flutterfire configure
so all the Firebase configuration files are added
flutterfire configure --project=your-firebase-project-id
Once you’ve done this, the app should run correctly on iOS, Android, and web.
And with that, let’s tackle macOS.
Content warning: this guide contains some sarcasm. 😬
Missing file libarclite_macosx.a
When running the app on macOS, the first error I’ve encountered is this:
As it turns out, there is a similar issue on iOS, which has been discussed on StackOverflow:
To solve this, I've adapted the code from this answer by replacing this code at the end of the macos/Podfile
:
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_macos_build_settings(target)
end
end
with this:
post_install do |installer|
# Ensure pods also use the minimum deployment target set above
# https://stackoverflow.com/a/64385584/436422
puts 'Determining pod project minimum deployment target'
pods_project = installer.pods_project
deployment_target_key = 'MACOSX_DEPLOYMENT_TARGET'
deployment_targets = pods_project.build_configurations.map{ |config| config.build_settings[deployment_target_key] }
minimum_deployment_target = deployment_targets.min_by{ |version| Gem::Version.new(version) }
puts 'Minimal deployment target is ' + minimum_deployment_target
puts 'Setting each pod deployment target to ' + minimum_deployment_target
installer.pods_project.targets.each do |target|
flutter_additional_macos_build_settings(target)
target.build_configurations.each do |config|
config.build_settings[deployment_target_key] = minimum_deployment_target
end
end
end
The platform version also needs to be set at the top of the Podfile:
platform :osx, '10.14'
At this stage, we can run the app again and marvel at these scary-looking logs on the console:
As it turns out, these are only warnings, and the app actually starts:
But let’s not be fooled by the appearances! For we’re about to encounter a bunch of runtime errors. 👇
Network error (such as timeout, interrupted connection or unreachable host) has occurred
If we try to sign in or create an account, this bad boy shows up!
To fix this, we can open the macos project in Xcode:
Then, open the “Signing & Capabilities” tab for the Runner target, and tick the “Outgoing Connections (Client)” checkbox under the “App Sandbox (Debug and Profile)” section:
Then, we can run the app from scratch and try to sign in again, only to be greeted with another error. 👇
An error occurred when accessing the keychain
This is such a lovely error message that I’m tempted to frame it in my office:
An error occurred when accessing the keychain. The NSLocalizedFailureReasonErrorKey field in the NSError.userInfo dictionary will contain more information about the error encountered
I’m sure my users would love to see this in production:
But clearly, it’s my fault. How could I possibly forget to add the “Keychain Sharing” capability in Xcode?
With that sorted, let’s run the app once again.
"Runner" has entitlements that require signing with a development certificate
This is the icing on the cake. 👇
If we look carefully, Xcode also tells us the same thing. 👇
Alright alright!
Assuming we already have an Apple developer account (who doesn’t? 😱), we can select it in the “Team” dropdown, click on “Enable Development Signing”, and Xcode will sort things out for us:
To sign your iOS and macOS apps, you need to enroll for an Apple developer account, which costs $99/year. 💰
Running one more time
Believe it or not, we’ve reached the end of this odyssey!
The app now runs correctly, and if we attempt to sign in, we’re redirected successfully to the profile page:
Bingo! 🎯
Conclusion
As we have seen, getting Flutter & Firebase Auth to work on macOS is simply a case of getting past these "trivial" errors:
- Missing file libarclite_macosx.a
- Network error (such as timeout, interrupted connection or unreachable host) has occurred
- An error occurred when accessing the keychain
- "Runner" has entitlements that require signing with a development certificate
On iOS, everything goes smoothly, and most certainly, code signing is not required just to debug the app on the simulator. So I’m very puzzled about why this is a thing on macOS.
Some Criticism
In sharing this guide, I genuinely wanted to help folks who, like me, have struggled with Flutter + Firebase + macOS.
But the current state of play doesn’t exactly scream “developer-friendly”.
In an ideal world, Flutter & Firebase apps should “just work” on macOS without jumping through all these hoops.
So I also hope the right people in the Flutter / Firebase / Invertase teams will take notice and make the necessary improvements.
To that extent, here are some suggestions:
- improve
flutterfire
so it automatically takes care of all the macOS setup steps - add a page to official docs explaining all the steps (and keep it up to date)
For now, I hope this guide will suffice.
Thanks for reading, and happy coding!