-
Notifications
You must be signed in to change notification settings - Fork 1
공유 딥링크 Firebase Dynamic Links → App Links 전환 #407
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,16 +6,15 @@ import android.net.Uri | |
| import android.os.Bundle | ||
| import androidx.activity.enableEdgeToEdge | ||
| import androidx.appcompat.app.AppCompatActivity | ||
| import com.google.firebase.dynamiclinks.FirebaseDynamicLinks | ||
| import com.runnect.runnect.application.PreferenceManager | ||
| import com.runnect.runnect.presentation.detail.CourseDetailActivity | ||
| import com.runnect.runnect.presentation.login.LoginActivity | ||
| import com.runnect.runnect.presentation.storage.mydrawdetail.MyDrawDetailActivity | ||
| import com.runnect.runnect.util.analytics.Analytics | ||
| import com.runnect.runnect.util.analytics.EventName | ||
| import com.runnect.runnect.util.analytics.EventName.Param | ||
| import com.runnect.runnect.util.dynamiclink.RunnectDynamicLink.KEY_PRIVATE_COURSE_ID | ||
| import com.runnect.runnect.util.dynamiclink.RunnectDynamicLink.KEY_PUBLIC_COURSE_ID | ||
| import com.runnect.runnect.util.link.RunnectShareLink.KEY_PRIVATE_COURSE_ID | ||
| import com.runnect.runnect.util.link.RunnectShareLink.KEY_PUBLIC_COURSE_ID | ||
| import dagger.hilt.android.AndroidEntryPoint | ||
| import timber.log.Timber | ||
|
|
||
|
|
@@ -26,7 +25,7 @@ class SchemeActivity : AppCompatActivity() { | |
| super.onCreate(savedInstanceState) | ||
|
|
||
| if (isUserLoggedIn()) { | ||
| handleDynamicLinks() | ||
| handleAppLink() | ||
| } else { | ||
| navigateToLoginScreen() | ||
|
Comment on lines
27
to
30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift Preserve the App Link through the login flow. When the user is logged out, this branch starts Pass the App Link to the login flow and route it after login succeeds. Apply the same behavior to public and private course links if login remains required for both. 🤖 Prompt for AI Agents
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 현재 코드 유지 (범위 밖으로 보류) 지적 자체는 타당하지만, 이 PR이 만든 회귀가 아니라 마이그레이션 이전부터 있던 동작입니다. 이번 PR 범위는 Firebase Dynamic Links → App Links 전환이고 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
현재 PR의 범위를 고려하면 이 코멘트는 블로킹하지 않겠습니다. 로그인 후 App Link를 복원하는 개선은 별도 작업으로 추적하는 것이 적절합니다. 원하시면 PR과 이 코멘트를 연결한 후속 GitHub Issue를 생성하겠습니다. You are interacting with an AI system. |
||
| } | ||
|
|
@@ -37,54 +36,45 @@ class SchemeActivity : AppCompatActivity() { | |
| return accessToken != "none" | ||
| } | ||
|
|
||
| private fun handleDynamicLinks() { | ||
| FirebaseDynamicLinks.getInstance().getDynamicLink(intent) | ||
| .addOnSuccessListener(this) { pendingDynamicLinkData -> | ||
| val link = pendingDynamicLinkData.link | ||
|
|
||
| if (link != null) { | ||
| val publicCourseId = getCourseId(link, KEY_PUBLIC_COURSE_ID) | ||
| val privateCourseId = getCourseId(link, KEY_PRIVATE_COURSE_ID) | ||
|
|
||
| val targetScreen = when { | ||
| publicCourseId != null -> "CourseDetail" | ||
| privateCourseId != null -> "MyDrawDetail" | ||
| else -> "unknown" | ||
| } | ||
| Analytics.logEvent( | ||
| EventName.SYS_DEEPLINK_OPEN, | ||
| Param.DEEPLINK_URL to link.toString(), | ||
| Param.TARGET_SCREEN to targetScreen | ||
| ) | ||
| private fun handleAppLink() { | ||
| val link = intent.data | ||
| if (link == null) { | ||
| Timber.e("FAIL: no data in intent") | ||
| finish() | ||
| return | ||
| } | ||
|
|
||
| when { | ||
| publicCourseId != null -> navigateToCourseDetail<CourseDetailActivity>( | ||
| publicCourseId | ||
| ) | ||
| val publicCourseId = getCourseId(link, KEY_PUBLIC_COURSE_ID) | ||
| val privateCourseId = getCourseId(link, KEY_PRIVATE_COURSE_ID) | ||
|
|
||
| privateCourseId != null -> navigateToCourseDetail<MyDrawDetailActivity>( | ||
| privateCourseId | ||
| ) | ||
| val targetScreen = when { | ||
| publicCourseId != null -> "CourseDetail" | ||
| privateCourseId != null -> "MyDrawDetail" | ||
| else -> "unknown" | ||
| } | ||
| Analytics.logEvent( | ||
| EventName.SYS_DEEPLINK_OPEN, | ||
| Param.DEEPLINK_URL to link.toString(), | ||
| Param.TARGET_SCREEN to targetScreen | ||
| ) | ||
|
|
||
| else -> { | ||
| Timber.e("FAIL: could not find course id") | ||
| finish() | ||
| } | ||
| } | ||
| } | ||
| } | ||
| .addOnFailureListener(this) { t -> | ||
| Timber.e("FAIL: getDynamicLink from intent : ${t.message}") | ||
| when { | ||
| publicCourseId != null -> navigateToCourseDetail<CourseDetailActivity>(publicCourseId) | ||
| privateCourseId != null -> navigateToCourseDetail<MyDrawDetailActivity>(privateCourseId) | ||
| else -> { | ||
| Timber.e("FAIL: could not find course id") | ||
| finish() | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private fun getCourseId(link: Uri, key: String): Int? { | ||
| return link.getQueryParameter(key)?.toInt() | ||
| return link.getQueryParameter(key)?.toIntOrNull() | ||
| } | ||
|
|
||
| private inline fun <reified T : Activity> navigateToCourseDetail(courseId: Int) { | ||
| Intent(this, T::class.java).apply { | ||
| putExtra(EXTRA_FROM_DYNAMIC_LINK, courseId) | ||
| putExtra(EXTRA_FROM_APP_LINK, courseId) | ||
| startActivity(this) | ||
| } | ||
| } | ||
|
|
@@ -97,7 +87,7 @@ class SchemeActivity : AppCompatActivity() { | |
| } | ||
|
|
||
| companion object { | ||
| const val EXTRA_FROM_DYNAMIC_LINK = "fromDynamicLink" | ||
| const val EXTRA_FROM_APP_LINK = "fromAppLink" | ||
| private const val TOKEN_KEY_ACCESS = "access" | ||
| } | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.