How to make Flutter Web and Universal Links coexist on Firebase Hosting

flutter

Recently, I needed to deploy a Flutter app directly on the Web. Since Flutter 2.0, It has been fairly simple to add Web support to an existing app.

I decided to write a small article in order to share my finding about how to host a Flutter Web app and an apple-app-site-association file on the same Firebase hosting deploy. This file is needed to provide Universal Link on iOS.

At the end of the article you will be able to deep link into iOS without needing a custom scheme thanks to Firebase Hosting!

Compile the app for the Web

Firstly, you need to add the Web support to your app.

To add web support to an existing you can run this command in your project folder with Flutter 2:

flutter create .

It will add a web folder. It will then be a matter of updating your packaging or following specific web instructions.

For instance, an app with more than 25 packages took only 30 minutes to migrate to Flutter Web. You only need to go through each package of your pubspec.yaml file and check if the package is compatible for the web or add the correct kIsWeb condition.

Once everything is updated to support Flutter Web, you can run this command:

flutter build web

If everything is successful you’ll have a folder web in the build folder!

Deploy to Firebase Hosting

For this second step, you need to activate Firebase Hosting directly on the Firebase console. Once it’s done, you can run the

firebase init

command and select the Hosting key by pressing space.

firebase_1

You can then select or create a Firebase project and choose these options:

? What do you want to use as your public directory? (public) build/web
? Configure as a single-page app (rewrite all urls to /index.html)? (y/N) y
? Set up automatic builds and deploys with GitHub? (y/N) N

Once it’s done, you can run the firebase deploy command to deploy your Website:

firebase deploy --only hosting

Add the apple-app-site-association file

Now we want to add the apple-app-site-association file in order to mutualize all the links to the same domain!

What I had to learn the hard way is that Apple outdated documentation is still living on the Apple website alongside the new documentation.
The example file I’ll show you is valid as of today (July 2021) but it should stay within the same idea.

Add an apple-app-site-association in the web/.well-known/ folder. The content of the file is the following:

{
"webcredentials": {
"apps": ["TEAMID.com.example.product"]
}
,
"applinks": {
"apps": [],
"details": [
{
"appID": "TEAMID.com.example.product",
"paths": ["*"],
"appIDs": ["TEAMID.com.example.product"],
"components": [
{
"/": "/*"
}
]
}
]
}
}

You’ll have to replace the TEAMID with your Apple Team ID and the com.example.product with your bundle ID.

Then replace your firebase.json file (generated at the previous step at the root of your project) with this:

{
"hosting": {
"public": "build/web",
"appAssociation": "NONE",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"headers": [
{
"source": "/.well-known/apple-app-site-association",
"headers": [
{
"key": "Content-Type",
"value": "application/json"
}
]
}
],
"rewrites": [
{
"source": "/.well-known/apple-app-site-association",
"destination": "/.well-known/apple-app-site-association"
},
{
"source": "**",
"destination": "/index.html"
}
]
}
}

You can then rebuild you build/web with the firebase build web command.

Once the compilation finished, you can relaunch your deploy command:

firebase deploy --only hosting

The apple-app-site-association should be present on your website at https://project-id.web.app/.well-known/apple-app-site-association.

You can use this tool to check if the apple-app-site-association is properly setup.

Conclusion

I tried to summarise and condense a maximum of my experience. If you need any more clarification don’t hesitate to ping me on Twitter @BeGuillaume.

Have a nice day!