Skip to content
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

GoogleApiManager$GooglePlayServicesMissingException - Google play services not available #2783

Open
anandwana001 opened this issue Oct 8, 2024 · 12 comments · May be fixed by #2924
Open

GoogleApiManager$GooglePlayServicesMissingException - Google play services not available #2783

anandwana001 opened this issue Oct 8, 2024 · 12 comments · May be fixed by #2924
Assignees
Labels
type: bug Something isn't working
Milestone

Comments

@anandwana001
Copy link
Collaborator

GoogleApiManager.installGooglePlayServices
com.google.android.ground.system.GoogleApiManager$GooglePlayServicesMissingException - Google play services not available

 Fatal Exception: com.google.android.ground.system.GoogleApiManager$GooglePlayServicesMissingException: Google play services not available
       at com.google.android.ground.system.GoogleApiManager.installGooglePlayServices(GoogleApiManager.kt:45)
       at com.google.android.ground.ui.startup.StartupViewModel.initializeLogin(StartupViewModel.kt:32)
       at com.google.android.ground.ui.startup.StartupFragment$onResume$1.invokeSuspend(StartupFragment.kt:55)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
       at kotlinx.coroutines.internal.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:367)
       at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:30)
       at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default(Cancellable.kt:25)
       at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:110)
       at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:126)
       at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:56)
       at kotlinx.coroutines.BuildersKt.launch(:1)
       at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:47)
       at kotlinx.coroutines.BuildersKt.launch$default(:1)
       at com.google.android.ground.ui.startup.StartupFragment.onResume(StartupFragment.kt:53)
       at androidx.fragment.app.Fragment.performResume(Fragment.java:3210)
       at androidx.fragment.app.FragmentStateManager.resume(FragmentStateManager.java:666)
       at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:310)
       at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:114)
       at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1675)
       at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3259)
       at androidx.fragment.app.FragmentManager.dispatchResume(FragmentManager.java:3191)
       at androidx.fragment.app.Fragment.performResume(Fragment.java:3219)
       at androidx.fragment.app.FragmentStateManager.resume(FragmentStateManager.java:666)
       at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:310)
       at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:114)
       at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1675)
       at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3259)
       at androidx.fragment.app.FragmentManager.dispatchResume(FragmentManager.java:3191)
       at androidx.fragment.app.FragmentController.dispatchResume(FragmentController.java:285)
       at androidx.fragment.app.FragmentActivity.onResumeFragments(FragmentActivity.java:333)
       at androidx.fragment.app.FragmentActivity.onPostResume(FragmentActivity.java:322)
       at androidx.appcompat.app.AppCompatActivity.onPostResume(AppCompatActivity.java:245)
       at android.app.Activity.performResume(Activity.java:8219)
       at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4814)
       at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4857)
       at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:54)
       at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
       at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176)
       at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2253)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loopOnce(Looper.java:201)
       at android.os.Looper.loop(Looper.java:288)
       at android.app.ActivityThread.main(ActivityThread.java:7870)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1009)
        
@anandwana001 anandwana001 added the type: bug Something isn't working label Oct 8, 2024
@anandwana001
Copy link
Collaborator Author

@shobhitagarwal1612 Is it the correct behaviour or should we close the app or something in such scenario?

@shobhitagarwal1612
Copy link
Member

We already handle this exception here.

@anandwana001
Copy link
Collaborator Author

We already handle this exception here.

Should we close this issue?
This is one of the crash seen in crashlytics today

@gino-m
Copy link
Collaborator

gino-m commented Nov 19, 2024

This crash has occurred 15 times in prod on v0.1.11. Prioritizing as P1.

@gino-m
Copy link
Collaborator

gino-m commented Nov 25, 2024

Let's show a more meaningful error message and exit instead of crashing.

@kenstershiro
Copy link
Collaborator

kenstershiro commented Dec 4, 2024

Agreed to show an error message on the UI and exit, and log in debug. @jo-spek can check the translations

@kenstershiro kenstershiro added this to the GA release milestone Dec 4, 2024
@anandwana001 anandwana001 moved this from Todo to In Progress in Ground Dec 6, 2024
@gino-m
Copy link
Collaborator

gino-m commented Dec 11, 2024

Agreed to show an error message on the UI and exit, and log in debug. @jo-spek can check the translations

@kenstershiro Unfortunately, Play services doesn't always report success or failure states correctly. In rare cases when we know we can't recover by asking the user to enable/install Play services, we can show an error. In other's we'll have to wait until the Play services are installed. Currently, we show the "Initializing..." spinner while that's happened. Perhaps we should add a distinct message for this case, e.g. "Waiting for Play services...". Wdyt?

@gino-m
Copy link
Collaborator

gino-m commented Dec 12, 2024

@anandwana001 The easy way to solve this would be to split the init method in StartupViewModel into two, and to show one progress dialog while initializing Play services, dismiss once done, then show the current initializing progress spinner while initializing the auth manager.

@kenstershiro
Copy link
Collaborator

kenstershiro commented Dec 12, 2024

Currently, we show the "Initializing..." spinner while that's happened. Perhaps we should add a distinct message for this case, e.g. "Waiting for Play services...". Wdyt?

Not sure the different message adds much value to the user, but if it's a simple change I'd agree.

@gino-m
Copy link
Collaborator

gino-m commented Dec 12, 2024

Not sure the different message adds much value to the user, but if it's a simple change I'd agree.

In some cases, the OS never lets the app know the installation of Google Play services fails, causing the app to get stuck showing "Initializing..." In those cases, the user doesn't know they can recover by installing Play services; showing the "Waiting for Play services..." will give them some indication of what the app is waiting for.

When Play services is already installed, we can avoid showing the new "Waiting" dialog altogether. @anandwana001

@gino-m
Copy link
Collaborator

gino-m commented Dec 13, 2024

The following fix in #2920 doesn't work as intended:

override fun onResume() {
super.onResume()
showProgressDialog(R.string.initializing)
viewLifecycleOwner.lifecycleScope.launch {
try {
viewModel.initializeLogin()
} catch (t: Throwable) {
onInitFailed(t)
}
}
}

viewModel.initializeLogin() will not loop until Play services is installed since StartupFragment and its scope are stopped when the app navigates to the Play services install/enable flow.

Instead, we should make sure the flow is correct when the user returns to the app.

@gino-m
Copy link
Collaborator

gino-m commented Dec 13, 2024

Currently, we show the "Initializing..." spinner while that's happened. Perhaps we should add a distinct message for this case, e.g. "Waiting for Play services...". Wdyt?

Not sure the different message adds much value to the user, but if it's a simple change I'd agree.

@kenstershiro @anandwana001 While debugging I realized we don't actually need this extra message, since when the user returns to the app from installing Play services, the init flow will happen again, which will in turn either pass directly to the sign in screen, or re-display the "install Play services" dialog. In that case the "Waiting for Play services.." progress spinner would never be shown.

@gino-m gino-m linked a pull request Dec 13, 2024 that will close this issue
@anandwana001 anandwana001 assigned gino-m and unassigned anandwana001 Dec 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug Something isn't working
Projects
Status: In Progress
4 participants