google-signin: SignIn() appears stuck and return nothing after the app reloads for several times on Android.

I’ve only tested the issue on Android.

The sign in works fine when the app starts. But after you log in , log out and reload for several times . The signIn() doesn’t return anything. You fire another signIn() and it throws this error:

In Progress error: Error: cannot set promise - some async operation is still in progress.

From now on, you can’t get any data from signIn() anymore unless you kill the app and start the app, but the problem never goes away as you reload the apps again for several times. You can go as many as 5 reloads without a problem (Sometimes as few as 1 reload), but the issue will eventually occur.

Related issue: https://github.com/react-native-community/react-native-google-signin/issues/475

Steps to Reproduce

https://github.com/stonecold123/signin-test

To run the app:

Update the Android SDK directory in ./android/local.properties

Create a new Android app in the firebase console and name it as com.signin.test

Add your debug keystore’s SHA1 value to the console, and download google-services.json to android/app

Add your web client ID in src/TestScreen.jsx

Expected Behavior

The signIn() should return data even after multiple reloads.

Actual Behavior

I suspect the signIn() is stuck and never gets resolved when the app reloads.

Environment

Please provide the version of your

Platform: Android

  "dependencies": {
    "react": "16.4.1",
    "react-native": "0.56.0",
    "react-native-firebase": "^4.3.8",
    "react-native-google-signin": "^1.0.0-rc3",
    "react-native-navigation": "^2.0.2477"
  },

‘com.android.tools.build:gradle:3.1.3’ ‘com.google.gms:google-services:3.2.1’

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 3
  • Comments: 47 (10 by maintainers)

Most upvoted comments

happening to me as well

I’m seeing the same issue. (Again.)

At this point I guess this is just an annoyance during debugging. But I’m nervous that CodePush reloads may also trigger this problem when we try to update our bundle post-deployment.

I know that the maintainers have looked at this before and couldn’t reproduce it or track it down. But I’m wondering if there is a way to build something into the API to allow client code to flush or cancel existing requests, or something. Even if it’s ugly.

There is a fix for a race condition issue in #623. If you still get signIn() to stuck please report here.

Yes,I just did what @ganesh-pprasad did.

I haven’t come across any error after changing the source code in RNGoogleSignInModule:

    private void handleSignInTaskResult(Task<GoogleSignInAccount> result) {
        try {
            GoogleSignInAccount account = result.getResult(ApiException.class);
            WritableMap params = getUserProperties(account);
            //new AccessTokenRetrievalTask(this).execute(params);
            new AccessTokenRetrievalTask(this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,params);

        } catch (ApiException e) {
            int code = e.getStatusCode();
            promiseWrapper.reject(String.valueOf(code), GoogleSignInStatusCodes.getStatusCodeString(code));
        }
    }

@jozan, @vonovak Would you consider using executeOnExecutor in the next version?

The issue still appears for me Both production and dev 1.2.1 version

We had this issue in our app, and a colleague of mine found the issue. Posting it here, before I send PR for you guys.

Our MainActivity.java looked like this (relevant parts).

public class MainActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler {
  private ReactRootView mReactRootView;
  private ReactInstanceManager mReactInstanceManager;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Setup react root view.
    mReactInstanceManager = getReactNativeHost().getReactInstanceManager();
    mReactRootView = new ReactRootView(this);
    mReactRootView.startReactApplication(mReactInstanceManager, getMainComponentName(), null);
    setContentView(mReactRootView);
  }

  @Override
  public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    // Notify the facebook sdk of the activity result.
    MainApplication.getCallbackManager().onActivityResult(
      requestCode,
      resultCode,
      data
    );
  }

Then in de onActivityResult you see super being called, but that is not enough to trigger the instance manager event. We still need to call onActivityResult on the mReactInstanceManager we created.

@Override
  public void onActivityResult(int requestCode, int resultCode, Intent data) {
    ...
    // --- ADD THIS ---
    if (mReactInstanceManager != null) {
      mReactInstanceManager.onActivityResult(this, requestCode, resultCode, data);
    }
  }

Now I think we added some non-standard code to get other parts of the app working, but assuming people add Google Signin, they also add Facebook Login and overwriting the onActivityResult on their MainActivity.java file. I also did a quick Google and see some boilerplates using the ReactInstanceManager.

Hope this helps some people out. Let me know so I can add it to the Android guide with a PR