firebase / FirebaseUI-Android

Optimized UI components for Firebase
https://firebaseopensource.com/projects/firebase/firebaseui-android/
Apache License 2.0
4.63k stars 1.83k forks source link

com.firebase.ui.auth.ui.idp.AuthMethodPickerActivity has leaked window #1008

Closed rvcdev closed 6 years ago

rvcdev commented 6 years ago

For reference, I checked the open and closed issues. All issues referencing the same type of exception were for older versions of FirebaseUI and the resolution was to update FirebaseUI to the latest version which included the fix. Here I am using the latest versions of FirebaseUI and their corresponding Google Play Services versions from the table included in the FirebaseUI README.

My Android-fu is by no means "pro", so if I've missed a step somewhere that is causing this, I'd appreciate any feedback.

Environment

Problem:

Steps to reproduce:

  1. Tap sign-in with Google button
  2. Observe loading animation
  3. After loading animation, observe that you are still seeing the sign-in buttons for social auth
  4. Tap sign-in with Google button
  5. Observe that you are now signed in and taken to MainActivity

Observed Results:

Tapping sign-in is required twice for Google Sign-in. First tap results in the following exception captured in logcat:

E/WindowManager: android.view.WindowLeaked: Activity com.firebase.ui.auth.ui.idp.AuthMethodPickerActivity has leaked window android.widget.FrameLayout{5f4b2d5 V.E...... ......I. 0,0-175,175} that was originally added here
                     at android.view.ViewRootImpl.<init>(ViewRootImpl.java:368)
                     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:299)
                     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
                     at com.zoho.livechat.android.ZohoLiveChat.showChatBubble(ZohoLiveChat.java:1895)
                     at com.zoho.livechat.android.ZohoLiveChat$1.onActivityResumed(ZohoLiveChat.java:1121)
                     at android.app.Application.dispatchActivityResumed(Application.java:214)
                     at android.app.Activity.onResume(Activity.java:1207)
                     at android.support.v4.app.FragmentActivity.onResume(FragmentActivity.java:446)
                     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1258)
                     at android.app.Activity.performResume(Activity.java:6312)
                     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3092)
                     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3134)
                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1388)
                     at android.os.Handler.dispatchMessage(Handler.java:102)
                     at android.os.Looper.loop(Looper.java:148)
                     at android.app.ActivityThread.main(ActivityThread.java:5417)
                     at java.lang.reflect.Method.invoke(Native Method)
                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
E/WindowManager: android.view.WindowLeaked: Activity com.google.android.gms.auth.api.signin.internal.SignInHubActivity has leaked window android.widget.FrameLayout{5a9bfaf V.E...... ......I. 0,0-175,175} that was originally added here
                     at android.view.ViewRootImpl.<init>(ViewRootImpl.java:368)
                     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:299)
                     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
                     at com.zoho.livechat.android.ZohoLiveChat.showChatBubble(ZohoLiveChat.java:1895)
                     at com.zoho.livechat.android.ZohoLiveChat$1.onActivityResumed(ZohoLiveChat.java:1121)
                     at android.app.Application.dispatchActivityResumed(Application.java:214)
                     at android.app.Activity.onResume(Activity.java:1207)
                     at android.support.v4.app.FragmentActivity.onResume(FragmentActivity.java:446)
                     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1258)
                     at android.app.Activity.performResume(Activity.java:6312)
                     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3092)
                     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3134)
                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1388)
                     at android.os.Handler.dispatchMessage(Handler.java:102)
                     at android.os.Looper.loop(Looper.java:148)
                     at android.app.ActivityThread.main(ActivityThread.java:5417)
                     at java.lang.reflect.Method.invoke(Native Method)
                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
E/WindowManager: android.view.WindowLeaked: Activity com.firebase.ui.auth.KickoffActivity has leaked window android.widget.FrameLayout{2081fbc V.E...... ........ 0,0-175,175} that was originally added here
                     at android.view.ViewRootImpl.<init>(ViewRootImpl.java:368)
                     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:299)
                     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
                     at com.zoho.livechat.android.ZohoLiveChat.showChatBubble(ZohoLiveChat.java:1895)
                     at com.zoho.livechat.android.ZohoLiveChat$1.onActivityResumed(ZohoLiveChat.java:1121)
                     at android.app.Application.dispatchActivityResumed(Application.java:214)
                     at android.app.Activity.onResume(Activity.java:1207)
                     at android.support.v4.app.FragmentActivity.onResume(FragmentActivity.java:446)
                     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1258)
                     at android.app.Activity.performResume(Activity.java:6312)
                     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3092)
                     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3134)
                     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2481)
                     at android.app.ActivityThread.-wrap11(ActivityThread.java)
                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                     at android.os.Handler.dispatchMessage(Handler.java:102)
                     at android.os.Looper.loop(Looper.java:148)
                     at android.app.ActivityThread.main(ActivityThread.java:5417)
                     at java.lang.reflect.Method.invoke(Native Method)
                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
E/WindowManager: android.view.WindowLeaked: Activity com.firebase.ui.auth.KickoffActivity has leaked window android.widget.FrameLayout{e88fb45 V.E...... ........ 0,0-175,175} that was originally added here
                     at android.view.ViewRootImpl.<init>(ViewRootImpl.java:368)
                     at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:299)
                     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
                     at com.zoho.livechat.android.ZohoLiveChat.showChatBubble(ZohoLiveChat.java:1895)
                     at com.zoho.livechat.android.ZohoLiveChat$1.onActivityResumed(ZohoLiveChat.java:1121)
                     at android.app.Application.dispatchActivityResumed(Application.java:214)
                     at android.app.Activity.onResume(Activity.java:1207)
                     at android.support.v4.app.FragmentActivity.onResume(FragmentActivity.java:446)
                     at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1258)
                     at android.app.Activity.performResume(Activity.java:6312)
                     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3092)
                     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3134)
                     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2481)
                     at android.app.ActivityThread.-wrap11(ActivityThread.java)
                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                     at android.os.Handler.dispatchMessage(Handler.java:102)
                     at android.os.Looper.loop(Looper.java:148)
                     at android.app.ActivityThread.main(ActivityThread.java:5417)
                     at java.lang.reflect.Method.invoke(Native Method)
                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Expected Results:

Relevant Code:

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.reallyvirtual.authenticator">
    <!-- For communicating with the Sim when it's offline. -->
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <!-- For communicating with the back-end and platform apps. -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- For determining if we can communicate with the back-end and platform apps. -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <meta-data
            xmlns:tools="http://schemas.android.com/tools"
            android:name="com.facebook.sdk.ApplicationId"
            android:value="@string/facebook_app_id"
            tools:replace="android:value"/>
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Project.gradle:

  // Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {

    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0'
        classpath 'com.google.gms:google-services:3.1.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven {
            url "https://maven.google.com" // Google's Maven repository
        }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

App.gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.reallyvirtual.authenticator"
        minSdkVersion 16
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        resConfigs "auto"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support:design:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'

    compile "com.google.android.gms:play-services-auth:11.4.2"

    // Zoho Mobilisten
    compile project(':Mobilisten')
    // Twitter
    compile("com.twitter.sdk.android:twitter-core:3.0.0@aar") { transitive = true }

    // Facebook SDK
    compile 'com.facebook.android:facebook-login:4.27.0'

    // Firebase Core Libs
    compile 'com.google.firebase:firebase-core:11.4.2'
    compile 'com.google.firebase:firebase-database:11.4.2'
    compile 'com.google.firebase:firebase-storage:11.4.2'
    compile 'com.google.firebase:firebase-auth:11.4.2'
    compile 'com.google.firebase:firebase-messaging:11.4.2'
    compile 'com.google.firebase:firebase-config:11.4.2'

    // Firebase UI
    compile 'com.firebaseui:firebase-ui-auth:3.1.0'
    compile 'com.firebaseui:firebase-ui-database:3.1.0'
    compile 'com.firebaseui:firebase-ui-storage:3.1.0'

    // Glide Imaging Lib
    compile 'com.github.bumptech.glide:glide:4.3.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.3.0'
}
apply plugin: 'com.google.gms.google-services'

MainActivity.java; AuthStateListener setup:

fireAuthStateListener = new FirebaseAuth.AuthStateListener() {
            @Override
            public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
                signedInUser = firebaseAuth.getCurrentUser();
                if (signedInUser != null) {
                    onSignedInInitialize();
                } else {
                    onSignedOutCleanup();
                    startActivityForResult(
                            AuthUI.getInstance()
                                    .createSignInIntentBuilder()
                                    .setIsSmartLockEnabled(!BuildConfig.DEBUG)
                                    .setAvailableProviders(
                                            Arrays.asList(
                                                    new AuthUI.IdpConfig.Builder(AuthUI.GOOGLE_PROVIDER).build(),
                                                    new AuthUI.IdpConfig.Builder(AuthUI.FACEBOOK_PROVIDER).build(),
                                                    new AuthUI.IdpConfig.Builder(AuthUI.TWITTER_PROVIDER).build(),
                                                    new AuthUI.IdpConfig.Builder(AuthUI.EMAIL_PROVIDER).build()))
                                    .setTosUrl(getString(R.string.tos_url))
                                    .setPrivacyPolicyUrl(getString(R.string.privacy_policy_url))
                                    .build(),
                            RC_SIGN_IN);
                }
            }
        };
yashnagda04 commented 6 years ago

yes, I am facing the same issue. Did you find any solution?

Kurt29 commented 6 years ago

I am not sure, but the refactoring @SUPERCILEX is doing should help with a lot of IDP and auth stuff. The hope is, that that is going to fix a lot of errors, bugs and so on, I think the focus is to finish it as fast as possible, instead of trying to fix them in FireBaseUI 3.1.* (except it's a fatal error) @SUPERCILEX correct me if I am in the wrong XD

rvcdev commented 6 years ago

@yash59 - No, I didn't find a fix. The issue still occurs.

@Kurt29 - Thanks for the feedback!

SUPERCILEX commented 6 years ago

@Kurt29 I believe this is just a memory leak, and yes, separating the UI and background work stacks should fix the numerous mini task listener and view leaks peppered throughout FirebaseUI.

Kurt29 commented 6 years ago

@Supercilex Since when is something β€œjustβ€œ a memory leak? XD

SUPERCILEX commented 6 years ago

@Kurt29 πŸ˜† yeah, sorry. I meant it's not the end of the world compared to a crash, but still definitely something we need to fix.

Kurt29 commented 6 years ago

πŸ˜‚ was just kidding That was what I meant with my comment, that there are some bugs with more priority.

SUPERCILEX commented 6 years ago

πŸ˜ŠπŸ‘

yashnagda04 commented 6 years ago

I have a production app on play store and many users are facing this issue. anyone have any idea or alternative to solve this issue?

SUPERCILEX commented 6 years ago

@rvcdev @yash59 I can't repro on v3.2.1... are you sure it requires 2 taps to start the Google sign-in flow? And the steps are just starting the flow and clicking on the Google button?

rvcdev commented 6 years ago

@SUPERCILEX - I was experiencing the problem in v3.1.0, I've since moved all sign-in related code to it's own SignInActivity and upgraded Firebase UI to v3.1.3 to match my updated build target for Android O. No more leaks during my sign-in flow and no more needing to tap any of the sign-in buttons more than once. :smile:

SUPERCILEX commented 6 years ago

Oh hey, sweet! @samtstern looks like this can be closed. 😁

samtstern commented 6 years ago

Nice!