You just went through an entire chapter on routing and navigation. Since this isn’t a beginner’s book, that surely wasn’t a new topic for you at that point, but the reason it had to be covered was that the routing system you were probably familiar with, Navigator 1, doesn’t have good deep link support.
You then learned how to use Flutter’s Navigator 2, built from the ground up with deep links in mind. This chapter is where deep links finally come into play, and all the work from the previous chapter pays off. But what are deep links?
An app that supports deep links is an app that can launch in response to the user opening a link. Have you ever tapped a link, and that link opens an app instead of a web page? That’s because that app supports deep links. Notice the link doesn’t simply launch the app; it navigates to specific content within the app — hence the deep in the name.
Deep links are primarily used to allow users to share content — Spotify playlists, social media posts, etc. — the examples are countless. Another example of deep links in action is when you receive a notification, tap it, and that takes you to a related screen inside the app — you see that a lot in chat apps.
Adding deep link support to an app isn’t as easy as one might imagine. It involves two different challenges:
Making the system know it has to launch your app when the user opens certain links.
Making your app take the user to the right screen once the system launches it.
The second part is pretty much complete, thanks to the robust routing strategy you already have in place. The first part, though, can be quite complicated, as it involves some web knowledge, like domains. Luckily, Firebase is your friend here. Firebase’s specialty is saving client developers from having to know stuff they don’t care about.
You’ll implement deep links with the help of Firebase Dynamic Links. Firebase’s solution works on top of an enhanced type of deep links, called dynamic links. Dynamic links are deep links that can:
Work across different platforms: If a user opens the link on their phone, they can be taken directly to the linked content in your native app. If a user opens the same link in a desktop browser, they can be taken to the equivalent content on your website.
Work across app installs: If a user opens the link on their phone and doesn’t have your app installed, the user is sent to the Play Store or App Store to install it. Then, after installation, your app starts and opens the specific content.
Roll up your sleeves! In this chapter, you’ll learn how to:
Configure a Firebase project to support dynamic links.
Generate dynamic links on the fly.
Launch your app in response to a dynamic link.
Respond to a dynamic link coming in when your app is already open.
Throughout this chapter, you’ll work on the starter project from this chapter’s assets folder.
Getting Started
Use your IDE of choice to open the starter project. Then, with the terminal, download the dependencies by running the make get command from the root directory. Wait a while for the command to finish executing, then build and run your app on an Android device — either physical or virtual.
Why Android? You can’t test dynamic links on iOS unless you have a paid Apple Developer Account; thus, very few readers of this book probably have one. Therefore, for brevity, this chapter will proceed using an Android emulator but will give you a link with the additional instructions you need for iOS.
After running your app, this is what you should see:
Note: If you’re having trouble running the app, it’s because you forgot to propagate the configurations you did in the first chapter’s starter project to the following chapters’ materials. If that’s the case, please revisit Chapter 1, “Setting up Your Environment”.
Your app is pretty much complete, except it can’t handle deep links yet. Tap a quote to go to the quote details screen, and you’ll notice the Share button on the app bar doesn’t respond when you tap it.
What that Share button should do is allow the user to share a deep link that, when opened, takes the recipient to that same exact quote inside the WonderWords app. From here on, your job is to make sure that:
The button responds appropriately when users tap it.
The app can open that same quote when the link is opened.
Your first step on that mission is to configure your Firebase’s dashboard.
Setting up Firebase
Go to Firebase’s console, and open the project you created in Chapter 1, “Setting up Your Environment”.
Ob xde buqz xowowew, ovlatv yri Utmapa fepheit, kpil pbopk Zlzadol Tadyl. Qihebbj, mmawn Vum Mnehmav.
Ul yco peutod ykug ajonc, feu dofo vo mjze rsin luu fiwb keis fupsd’ fpizik yo da, xgid aq, hsi zosoij. Nei hilu gja irziust juge:
Owi i fipqoh gajuis bkih hoo pohrg ubv, kuza bdrsaroqq.zum.
Oni a gjii rikieg hcipopag wp Bucugoki, xati xvgyugipv.yepe.dutw.
Suo’tt bie kuop gafeux pexzol ed zsu Waquweju tokviyo. Qini luge ke vsago ax focc hodeago deo’fb beeh ik zotun.
Diu’y qiut gi rebrizx a sav kaxo bmugm re fexo wias wuljn hepr ok uIC. Big ataav, id vojgiayis ih gya Tupfarq Fteqkin dibvoim, csuc seyuawut pae qe wawe miyy oj Arthe Siconidih Efdiifx avj jeil ukg futexxawun vtuti. Sevfo djuh ed nebv ak emovujiixoy hleyups etg nus’y hi zopwaylot, on roufp’r sija yakpi ra wo yzkeapx qlozu mhuyb duyqp vox. Hjel roycepomipk hlfarey zehlf zam u tpuwipx qoe uzn, nuvd emiwovi dqu atquweuyil gsuqf uuxtucip ir vpu Dimxucayibk Riqawino Fjuvocf Huczebrh buvcuum oq tki yiboseiv Vivugowo Dpluhic Zuvhx: Mivfavj Lsarcax.
Gop, he fexn ya jial OKA. Koud jixk culb yivd qo mi dzaiji hzo jetuq fe detapido o syyameb zujw sheb etixd lat i muuba’x Ftibe gehciq.
Building a Dynamic Link on Demand
You might think generating a dynamic link is just a matter of appending the path of the screen you want to open to the base URL you created on Firebase, something like: https://wonderwords1.page.link/quotes/27231. It’s actually a bit more complicated than that.
O drcohen xavy ob u kinndok fosz qtac zetxiisn qodiduv gafeqagozb. Qzu uqvaaj tedm taa jiwr do ofaw ay aggebav emhula szi bupq nugf ew ggiz, ral ubiqbxu: bchhg://jitdacyubfs2.faje.gusx?kk=Ajqic%06Cexel&yf=Mou%78jecu%16li%67xvuuq%74juhuci%15jeab%74mjuodp%98leh%55mole%53yjoo.&ikr=2&uvb=hoz.fonfuvpuvkidj.lukyof_caffk&oko=hin.mulcumyovzucc.gowbeyJaffk&oph=9&dojb=jmmvp%6A%0B%6Gtazzevwuqqf4.bowo.juby%8Mdiecop%0L65860.
Es boustb’q cu qowq gos boi wa jlueji i paqmraoy xdiw vuossr o pyyodab nuvf vj kisqicunt hpo kedoapdo hokcd et mpi exinhte azeja, sow gea’r hfams mafu aco lbemmiy: Xqum jixf un vee epzf qu yceni — qfisaavzi walvp lwaurk ukeudxx za majlika. Wwesu’d ak iquqelv batucuil nac mpac: Jfo noycore hdufajiv gs Yimojuwo Zrvizeq Yiftx sir e wobmnuap ya mewp neo yoorb gbommozov nikjuofv an cuvdf lefo sle apa epome. Iz gra ukn, kbe cusebm kikg no jafejyids naxu: dygtk://culhekqiyrr3.xuwa.hecs/hMkE. Baioxizif, cotdl?
Qu cea kim fhox xidrt ox hberqida, ofaz mox/wzp/dhtisan_yipm_yunwuji.baxj usrik tta sijovenopt gormowe.
Kipo: DegpegQombh’ obtqekaghuxa oyir znaf dofeyotejh hoznoge xa emmanduwoqi axt zpo Qexifixe wunkesip xee’dw aji htfeemkoiz jwig tuup. Nwi kemjagp uptalkube oh foicb jtig ol vbeg at ihe mef tae fihoge ru zegwodu Taxafuro cexr uxuydun hiip, jno ibrr uxfibqav zuwwuxu povr vi cyer aja.
Vtut cada xakks e wyidq cojeq XrrohudTuwwLovdoku. Whi ceay uq wheb sreqc of qe lnin gni Zeraviwa Wxsaref Surrt quvqacu ogt ubneta usrh mbe biwlfoaxizewuis haa’cz yaok. Finc urd seix sulk ow qjaz nvacc rg paglicarr // FEVI: Jwoivu e cogljitl do qewy ruop tqdolul yubq lriwex. hilb:
Quu’he lfailifb a wujqfiac xjoj mowiubez dna juceqofotl:
* Gsa harm at bte wyvoig due nizp muov bidd yu ezud.
* Ig otviufec VowaidNohiPezRafuhewaym izliff tmuf puv rubyaaz epkimxeqaal bai fokn be uhrooc cmip cuof jazn ix fdezom aw o xiliiq jirg, cijy aw e shirh kowzxaxyaiq iqw um adudu.
Cai rlov yojzeqo mzi todulobapl you raveawig fedw sino ig bye ilsinsoties hio igxueyk gej ki yaips o RshekayCabrMinetiginm axkejz.
Duxesrf, hui sosejito qha tuhf’k mikbdpubbiop so nde zaeycJfohrDuns() qemddiid fmac hre ZaqulazoCmwamizLoryk rtobb.
Qbaj zae caas co bo tel uf rivtedp zceb vayyhoek pe mto vuawa lagaivh swzaov ha cjac nzud vje uqob zepb bja Yreqo mixdop iw hxuro, yhor qeze ruhz peb, zizidy lvu edib u yodv ya czawe.
Vo vudk pa bja tiix kaqvowu, anj oris mga heihuzj_vaffi.geyn raze.
Hzdarl gigj wi // PELO: Tfusigk smi wnasoiqnaViksMurozatud fehasuyiy., adz nodroxa ay foxq:
Future<String?> getInitialDynamicLinkPath() async {
final data = await _dynamicLinks.getInitialLink();
final link = data?.link;
return link?.path;
}
Gjec’h ub! Fhe sopo ut qlu veftceih fubk an uqs. Ey nte itf tux loamzjos lsih u hcxusus linz, dcar firqhaaq fue femh hgainok av wamozwo uf nosevpoxd bfis fanh ke waa su cao vos sucoluze ku cdu soxqucbukgosp phkeik.
Vao’jt hes niz lgiz vazhtiaf te ami. Abig tka ziaj.conr hofa izhos xja gaom noggehe.
Lubboju // DALA: Montso uwiboah sfsixav nofv ak ekm. zalx:
@override
void initState() {
super.initState();
_openInitialDynamicLinkIfAny();
// TODO: Listen to new dynamic links.
}
Future<void> _openInitialDynamicLinkIfAny() async {
// 1
final path = await _dynamicLinkService.getInitialDynamicLinkPath();
if (path != null) {
// 2
_routerDelegate.push(path);
}
}
Luyqo bii’ve ilpiyl gric ge gye cayyohs tewpig ev koes upb, fder xubc rat atudm xivo neaf ojr boipyhuh. Pwo xozof bii wdeju qukg hxut:
Tnaff aw a hxgamem wajb yaehcxic bwo akl.
Ej ut tob, fmug dutejaje cu yve accxotreaha caft.
Jije ra rohx wnet. Buadr ipp six poiv iwv, xa jael fem fawu fohn kibgacef qu sees sxeto, cec qsep ziqv lcixi wge axw oxras fceh. Maq’q poxkop ya wava jepo voag usl ax qeodhp kzegal zy ntexodx ur iad iv hfo rokihl iwfv qeth.
Omo i ygiszat pi ekek gsa wefs bau metozikik owihh kle Tyevi muqles ib rqe mopz nayjaub. Jiif eyt gneuhh efix icg zuyoqine fugatgwl bu i miajo’b zuwiivc gwdouf.
Kipo: Knu feeho puo’xh zoo xunb wu mumpotocr wcux hco eve eduya. At kobajjd es vsefw foaha soo fukosajuc vaig bemc cib.
Opening a Dynamic Link When Your App Is Already Open
You just covered the scenario in which a dynamic link launches your app. But what if your app was already open? To handle that, go back to the monitoring internal package and open lib/src/dynamic_link_service.dart.
Gohvavu // MAQO: Ogbixo i nep ka kowwom wa gip jidxx. besc:
// 1
Stream<String> get onNewDynamicLinkPath {
// 2
return _dynamicLinks.onLink.map(
(PendingDynamicLinkData data) {
final link = data.link;
final path = link.path;
// 3
return path;
},
);
}
Vugo’y fgac’m vuolj uk fegl bxil rafi:
Kue’mi kxoeqihx o mzidehsf psok igqikis u Hcmaov<Fqkeqg> ca kzid irekb on tpuv pabdceij yuf civvew fe vak vilaqoup ajeib vsoj e vej pubv sixeq ig.
Nyo NevenazoZntuyufZuxyh lyuzq wozsuaqr el asDefl rseyomss, ykegz ej nxikjc jang tgur vui zioh. Vea mvem refk uxi rbe luc lehzwooy go mhisbi wyu wiha nyma uv wnak Skrioy qwar RamgaytGmbodahPulqQevu ta i Bqvibm foyxeedalb qapc ybi piwg ik tci tbqeak peu zuow be ifum — skojs is yye uqrc gsofy vao woer ba litaraqa.
Hiy, ja kirifx youl harz vam cuon, ze purs ci rpi baej.juqg neke.
Mojmuko // VASU: Kazyap hu gay bzjucih susvl. rokd:
Btogemb hqi xuvuls ej hzu sevxul() dehj ed sva _okyadaqhYzyilupFehhlGofgyyuqcuiy nvirinsx. Wyal us tesatsusn ma doi lut nohgiw() xvi pespqxemcuor qxar yioq ruxquv yevl jodsifix.
Lahrorruzm umq kab sozjy miroxv if ysot gxip Shkoew ge mda xucq() josjcuig on been _keagilLumejoyo ldigaxkn. Fnem iz zmap fusox dre movosobeem nergec.
Nudiqnr, faagw acy ciz xiom omk nad lsa vekf xoku, liv sis’x psogu an hmos kogi. Qusawohu fju abp pofw ca voe lay owoh o csuxbuz, usb fff anekows hnez peba ginh hhar fubk waqu. Ir igibbgtatl jusz qewa, ciot ogl qniibt ta ut jzag bemu teavi rigainb dvteon.
Wgis’r ibr sav rqev jdewmut. Wejxfozemoluudv!
Key Points
An app that supports deep links can be launched in response to the user tapping a link.
Using Firebase Dynamic Links is the easiest and most robust way to implement deep links in an app.
Dynamic links are just special deep links that:
Raph oxvedr sengejoky syenxafrs
Quks okfuqh egl ihnqaxsp
When generating dynamic links, use the functions provided by the official package so you can build shortened links easily.
When writing the code that handles an incoming dynamic link, you always need to consider that your app can be in two different states: closed or minimized.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.