1+ package com.google.firebase.quickstart.deeplinks.kotlin
2+
3+ import android.content.Intent
4+ import android.net.Uri
5+ import android.util.Log
6+ import androidx.lifecycle.ViewModel
7+ import androidx.lifecycle.ViewModelProvider
8+ import androidx.lifecycle.viewModelScope
9+ import androidx.lifecycle.viewmodel.CreationExtras
10+ import com.google.firebase.dynamiclinks.FirebaseDynamicLinks
11+ import com.google.firebase.dynamiclinks.PendingDynamicLinkData
12+ import com.google.firebase.dynamiclinks.ktx.androidParameters
13+ import com.google.firebase.dynamiclinks.ktx.dynamicLink
14+ import com.google.firebase.dynamiclinks.ktx.dynamicLinks
15+ import com.google.firebase.dynamiclinks.ktx.shortLinkAsync
16+ import com.google.firebase.ktx.Firebase
17+ import kotlinx.coroutines.flow.MutableStateFlow
18+ import kotlinx.coroutines.flow.StateFlow
19+ import kotlinx.coroutines.launch
20+ import kotlinx.coroutines.tasks.await
21+
22+ class DynamicLinksViewModel (
23+ private val dynamicLinks : FirebaseDynamicLinks
24+ ): ViewModel() {
25+
26+ private val _deepLink = MutableStateFlow (" " )
27+ val deepLink: StateFlow <String > = _deepLink
28+
29+ private val _shortLink = MutableStateFlow (" " )
30+ val shortLink: StateFlow <String > = _shortLink
31+
32+ private val _validUriPrefix = MutableStateFlow (true )
33+ val validUriPrefix: StateFlow <Boolean > = _validUriPrefix
34+
35+ fun getDynamicLink (intent : Intent ) {
36+ viewModelScope.launch {
37+ try {
38+ val pendingDynamicLinkData: PendingDynamicLinkData = dynamicLinks
39+ .getDynamicLink(intent)
40+ .await()
41+
42+ val deepLink: Uri ? = pendingDynamicLinkData.link
43+
44+ // Handle the deep link. For example, open the linked
45+ // content, or apply promotional credit to the user's
46+ // account.
47+ // ...
48+
49+ // Display deep link in the UI
50+ if (deepLink != null ) {
51+ _deepLink .value = deepLink.toString()
52+ } else {
53+ Log .d(TAG , " getDynamicLink: no link found" )
54+ }
55+ } catch (e: Exception ) {
56+ Log .w(TAG , " getDynamicLink:onFailure" , e)
57+ }
58+ }
59+ }
60+
61+
62+ /* *
63+ * Build a Firebase Dynamic Link.
64+ * https://firebase.google.com/docs/dynamic-links/android/create#create-a-dynamic-link-from-parameters
65+ *
66+ * @param deepLink the deep link your app will open. This link must be a valid URL and use the
67+ * HTTP or HTTPS scheme.
68+ * @param minVersion the `versionCode` of the minimum version of your app that can open
69+ * the deep link. If the installed app is an older version, the user is taken
70+ * to the Play store to upgrade the app. Pass 0 if you do not
71+ * require a minimum version.
72+ * @return a [Uri] representing a properly formed deep link.
73+ */
74+ // @VisibleForTesting
75+ fun buildDeepLink (uriPrefix : String , deepLink : Uri , minVersion : Int ): Uri {
76+ // Set dynamic link parameters:
77+ // * URI prefix (required)
78+ // * Android Parameters (required)
79+ // * Deep link
80+ // Build the dynamic link
81+ val link = Firebase .dynamicLinks.dynamicLink {
82+ domainUriPrefix = uriPrefix
83+ androidParameters {
84+ minimumVersion = minVersion
85+ }
86+ link = deepLink
87+ }
88+
89+ // Return the dynamic link as a URI
90+ return link.uri
91+ }
92+
93+ // @VisibleForTesting
94+ fun buildShortLinkFromParams (uriPrefix : String , deepLink : Uri , minVersion : Int ) {
95+ // Set dynamic link parameters:
96+ // * URI prefix (required)
97+ // * Android Parameters (required)
98+ // * Deep link
99+
100+ try {
101+ viewModelScope.launch {
102+ val shortDynamicLinks = Firebase .dynamicLinks.shortLinkAsync {
103+ link = deepLink
104+ domainUriPrefix = uriPrefix
105+ androidParameters {
106+ minimumVersion = minVersion
107+ }
108+ }.await()
109+
110+ val shortLinks = shortDynamicLinks.shortLink
111+ // val flowChartLink = shortDynamicLinks.previewLink
112+
113+ _shortLink .value = shortLinks.toString()
114+ }
115+ } catch (e: Exception ) {
116+ Log .e(TAG , e.toString())
117+ }
118+ }
119+
120+ fun validateAppCode (uriPrefix : String ) {
121+ if (uriPrefix.contains(" YOUR_APP" )) {
122+ _validUriPrefix .value = false
123+ }
124+ }
125+
126+ companion object {
127+ const val TAG = " DynamicLinksViewModel"
128+
129+ // Used to inject this ViewModel's dependencies
130+ // See also: https://developer.android.com/topic/libraries/architecture/viewmodel/viewmodel-factories
131+ val Factory : ViewModelProvider .Factory = object : ViewModelProvider .Factory {
132+ @Suppress(" UNCHECKED_CAST" )
133+ override fun <T : ViewModel > create (
134+ modelClass : Class <T >,
135+ extras : CreationExtras
136+ ): T {
137+ // Get Remote Config instance.
138+ val dynamicLinks = Firebase .dynamicLinks
139+ return DynamicLinksViewModel (dynamicLinks) as T
140+ }
141+ }
142+ }
143+ }
0 commit comments