thebergamo / react-native-fbsdk-next

MIT License
682 stars 167 forks source link

LoginManager.logInWithPermissions never resolve or reject its promise #105

Closed arnaud9145 closed 2 years ago

arnaud9145 commented 3 years ago

🐛 Bug Report

LoginManager.logInWithPermissions never resolve or reject its promise, but LoginButton works fine (tested on iOS only)

To Reproduce

I followed the tutorial, added code in AppDelegate.m, Info.plist. called Settings.initializeSDK() in a useEffect.

When I call the example code with LoginManager.logInWithPermissions (with .then or with async/await), the native modal "wants to use 'facebook.com'to sign in" appears. if I press cancel, the function resolve a cancel event. If i press "continue", a webview opens, I log in facebook, the modal closes, and nothing happens. The logInWithPermissions does not resolve, as if the webview is still opened.

Note : I added LoginButton next to my code, when the webview closes, the loginbutton changes to a Logout button, meaning that I did Log in successfully, only the callback is broken somewhere

Expected Behavior

logInWithPermissions should either resolve an object or throw an error. Note that LoginButton works perfectly fine

Code Example

import {AccessToken, LoginManager} from 'react-native-fbsdk-next';

const onFacebookButtonPress = async () => {
  try {
    // Attempt login with permissions
    const result = await LoginManager.logInWithPermissions(['public_profile']);
    // stuck here

    if (result.isCancelled) {
      throw 'User cancelled the login process';
    }

    // Once signed in, get the users AccessToken
    const data = await AccessToken.getCurrentAccessToken();

    if (!data) {
      throw 'Something went wrong obtaining access token';
    }

  } catch (error) {
    console.log(error);
  }
};

Environment


"react-native-fbsdk-next": "^4.4.1"

System:
    OS: macOS 11.6
    CPU: (8) x64 Intel(R) Core(TM) i7-8557U CPU @ 1.70GHz
    Memory: 264.71 MB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 14.17.5 - ~/.nvm/versions/node/v14.17.5/bin/node
    Yarn: 1.22.11 - /usr/local/bin/yarn
    npm: 6.14.14 - ~/.nvm/versions/node/v14.17.5/bin/npm
    Watchman: 2021.08.02.00 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.10.1 - /Users/arnaud/.rvm/gems/ruby-2.4.0/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 14.5, DriverKit 20.4, macOS 11.3, tvOS 14.5, watchOS 7.4
    Android SDK:
      API Levels: 26, 27, 28, 29, 30
      Build Tools: 27.0.3, 28.0.3, 29.0.2, 29.0.3
      System Images: android-29 | Google APIs Intel x86 Atom, android-30 | Google APIs Intel x86 Atom, android-30 | Google Play Intel x86 Atom
      Android NDK: Not Found
  IDEs:
    Android Studio: 4.1 AI-201.8743.12.41.7199119
    Xcode: 12.5.1/12E507 - /usr/bin/xcodebuild
  Languages:
    Java: 1.8.0_265 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.1 => 17.0.1
    react-native: 0.64.0 => 0.64.0
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found
arnaud9145 commented 3 years ago

update :

When I use LoginButton, the onLoginFinished callback is called, but if I try to call AuthenticationToken.getAuthenticationTokenIOS() or AccessToken.getCurrentAccessToken(), the execution gets stuck at those methods too. I must have missed a step somewhere, probably in the native side ?

Here's my AppDelegate.m juste in case :

#import "AppDelegate.h"

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <CodePush/CodePush.h> // @codepush
#import <Firebase.h> // @firebase
#import <StartupTrace.h> // @firebase-perf
#import <FBSDKCoreKit/FBSDKCoreKit.h> // @facebook

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  // #ifdef FB_SONARKIT_ENABLED
  //   InitializeFlipper(application);
  // #endif

  // @firebase
  if ([FIRApp defaultApp] == nil) {
    [FIRApp configure];
    [StartupPerformanceTrace start]; // @firebase-perf
  }

  // @facebook
  [[FBSDKApplicationDelegate sharedInstance] application:application
                          didFinishLaunchingWithOptions:launchOptions];

  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
                                                   moduleName:@"Cinemate"
                                            initialProperties:nil];

    if (@available(iOS 13.0, *)) {
      rootView.backgroundColor = [UIColor systemBackgroundColor];
  } else {
      rootView.backgroundColor = [UIColor whiteColor];
  }

  self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
  UIViewController *rootViewController = [UIViewController new];
  rootViewController.view = rootView;
  self.window.rootViewController = rootViewController;
  [self.window makeKeyAndVisible];
  return YES;
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
  return [CodePush bundleURL]; // @codepush
#endif
}

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
            options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
{
  [[FBSDKApplicationDelegate sharedInstance] application:application
                                                 openURL:url
                                                 options:options];
  return YES;
}

// - (BOOL)application:(UIApplication *)application
//             openURL:(NSURL *)url
//             options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
// {
//   // @facebook
//    if ([[FBSDKApplicationDelegate sharedInstance] application:application openURL:url options:options]) {
//     return YES;
//   }

//   // if ([RCTLinkingManager application:application openURL:url options:options]) {
//   //   return YES;
//   // }

//   return NO;
// }

//- (void)applicationDidBecomeActive:(UIApplication *)application {
//  [FBSDKAppEvents activateApp];
//}

// - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//   [[FBSDKApplicationDelegate sharedInstance] application:application
//                            didFinishLaunchingWithOptions:launchOptions];
//   return YES;
// }

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
  return [[FBSDKApplicationDelegate sharedInstance] application:application
                                                         openURL:url
                                               sourceApplication:sourceApplication
                                                      annotation:annotation];
}

@end
mikehardy commented 3 years ago

Not sure what's going on but I know @MilanObradovic just had a different problem with loginWithPermissions where the result appeared to be that it was working on both platforms, perhaps he has some insight?

arnaud9145 commented 3 years ago

I think I found it, I had the same problem adding apple signin. So I wondered if an other dependency might be breaking the native code of facebook/apple login. So I removed reanimated 2 lib, and apple signin worked ! Haven't tried yet with facebook signin, but seems to be exactly the same problem. I will try to solve the problem on the reanimated side, and if I can't, I will try to put an issue on the reanimated repository :)

I keep the issue opened for now, will update it later if I found a solution next week.

mikehardy commented 3 years ago

I use reanimated in combination with apple sign in and facebook. Just patched them for the upcoming rn66 release even https://github.com/software-mansion/react-native-reanimated/pull/2478

mikehardy commented 3 years ago

I'm certain it worked for me on android RN65.1+reanimated 2.2.2 but I'm on RN66.0+reanimated 2.2.3 now (shouldn't be different?) and I just tested a logout/login cycle for my app on android via facebook, it worked. No reproduction?

SebastianMieszczanczyk commented 3 years ago

Sorry, my issue is more suitable to this one: https://github.com/thebergamo/react-native-fbsdk-next/issues/52

bb-cuongnv commented 3 years ago

I also have the same problem. I'm using:

arnaud9145 commented 3 years ago

Turns out it was due to storybook on my side. Not sure exactly what in storybook broke fb connect, maybe a mock or something, but since I did not needed it, I simply removed it for now. I will build a different app for storybook later, I do not need to have storybook in my main app.

Sorry for the late response

marioscialpi commented 2 years ago

same here with android

mikehardy commented 2 years ago

react-native-fbsdk-next: 4.6.0

Please try to reproduce with current versions, a lot of time was just invested getting the native SDKs up to date. May not make a difference, but reproducing on old versions is not an efficient use of time as it can lead to troubleshooting already fixed items

marioscialpi commented 2 years ago

react-native-fbsdk-next: 4.6.0

Please try to reproduce with current versions, a lot of time was just invested getting the native SDKs up to date. May not make a difference, but reproducing on old versions is not an efficient use of time as it can lead to troubleshooting already fixed items

I've updated to the latest version

but the issue is still here: reject is not resolved

Possible Unhandled Promise Rejection

LoginManager.logInWithPermissions(['public_profile'])
      .then( 
        (result: LoginResult) => {
          // ok
        },
        (error: any) => {
          // **issue: never called**
        }
      )
mikehardy commented 2 years ago

So if you see Possible Unhandled Promise Rejection and you don't have a .catch, you have a code error. What happens when you add a .catch ?

marioscialpi commented 2 years ago
LoginManager.logInWithPermissions(['public_profile'])
      .then( 
        (result: LoginResult) => {
          // ok
        }
      )
      .catch(error => {
        // same here: **never called**
      });
mikehardy commented 2 years ago

Gonna need a https://stackoverflow.com/help/minimal-reproducible-example on this one I think, because I simply do not reproduce this.

Note that there is something fun going on that "rhymes" with this (that is: may be related) - network hangs etc https://github.com/facebook/react-native/issues/32001#issuecomment-971305939

marioscialpi commented 2 years ago
LoginManager.logInWithPermissions(['public_profile'])
      .then( 
        (result: LoginResult) => {
          // !!!! Possible Unhandled Promise Rejection was here !!!!
        }
      );

@mikehardy I'm sorry. Thanks for your time

Mario

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

robbie-c commented 2 years ago

Just adding this comment in case anyone else comes across this from a Google search like I did. You'll get this exact problem on iOS if you don't set up your application delegate correctly.

It'll work just fine if the user doesn't have the FB app installed, but won't if they do. You need to add something like:

(BOOL)application:(UIApplication *)application
          openURL:(NSURL *)url
          options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
  return [[FBSDKApplicationDelegate sharedInstance] application:application openURL:url options:options];
}
sagark1510 commented 2 years ago

@mikehardy I'm having the same issue. the promise never resolves or rejects. I added debug point in Xcode and it seems the result from FB is coming but the resolve part is actually not resolving to JS for some reason. I created whole new app to reproduce this issue but it seems to be working fine there. Now I don't know which of my package is giving this issue coz everything just works fine apart from this promise issue. I know you won't be able to help without reproducible demo but could you point me the steps how can I debug it and fix it or how can I find the culprit? adding the package.json here.

{
  "name": "xxx",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    ...
  },
  "config": {
    "react-native-storybook-loader": {
      "searchDir": [
        "./src",
        "./packages"
      ],
      "pattern": "**/*.stories.tsx",
      "outputFile": "./storybook/storyLoader.js"
    }
  },
  "dependencies": {
    "@gorhom/bottom-sheet": "^4",
    "@react-native-async-storage/async-storage": "^1.17.3",
    "@react-native-community/hooks": "^2.8.1",
    "@react-native-community/netinfo": "^8.2.0",
    "@react-navigation/native": "^6.0.10",
    "@react-navigation/native-stack": "^6.6.1",
    "@reduxjs/toolkit": "^1.8.1",
    "@sentry/react-native": "^3.4.1",
    "axios": "^0.26.1",
    "deepmerge": "^4.2.2",
    "i18next": "^21.6.16",
    "lodash": "^4.17.21",
    "react": "17.0.2",
    "react-i18next": "^11.16.8",
    "react-native": "0.68.1",
    "react-native-code-push": "^7.0.4",
    "react-native-config": "^1.4.5",
    "react-native-device-info": "^8.7.0",
    "react-native-fast-image": "^8.5.11",
    "react-native-fbsdk-next": "^8.0.2",
    "react-native-gesture-handler": "^2.4.1",
    "react-native-image-crop-picker": "^0.37.3",
    "react-native-linear-gradient": "^2.5.6",
    "react-native-paper": "^4.12.0",
    "react-native-parsed-text": "^0.0.22",
    "react-native-permissions": "^3.3.1",
    "react-native-reanimated": "^2.8.0",
    "react-native-safe-area-context": "^4.2.4",
    "react-native-screens": "^3.13.1",
    "react-native-svg": "^12.3.0",
    "react-native-vector-icons": "^9.1.0",
    "react-redux": "^7.2.8",
    "redux": "^4.1.2",
    "redux-persist": "^6.0.0",
    "redux-thunk": "^2.4.1"
  },
  "devDependencies": {
    "@babel/core": "^7.12.9",
    "@babel/runtime": "^7.12.5",
    "@react-native-community/eslint-config": "^2.0.0",
    "@storybook/addon-actions": "^5.3",
    "@storybook/addon-knobs": "^5.3",
    "@storybook/addon-links": "^5.3",
    "@storybook/addon-ondevice-actions": "^5.3.23",
    "@storybook/addon-ondevice-knobs": "^5.3.25",
    "@storybook/react-native": "^5.3.25",
    "@storybook/react-native-server": "^5.3.23",
    "@types/jest": "^26.0.23",
    "@types/react-native": "^0.67.4",
    "@types/react-native-vector-icons": "^6.4.10",
    "@types/react-test-renderer": "^17.0.1",
    "babel-jest": "^26.6.3",
    "babel-loader": "^8.2.3",
    "eslint": "^7.32.0",
    "jest": "^26.6.3",
    "metro-react-native-babel-preset": "^0.67.0",
    "prettier": "^2.6.2",
    "react-dom": "17.0.2",
    "react-native-storybook-loader": "^2.0.4",
    "react-native-svg-transformer": "^1.0.0",
    "react-test-renderer": "17.0.2",
    "typescript": "^3.8.3"
  },
  "resolutions": {
    "@types/react": "^17"
  },
  "jest": {
    "preset": "react-native",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx",
      "json",
      "node"
    ]
  }
}

Thank you for your help already.

mikehardy commented 2 years ago

In my experience with similar issues on react-native-firebase, redux messes up promise behavior. Philosophically the best way to reproduce is to "bisect". Remove half the dependencies (just brutally comment out code as needed to make that happen, it's an exploration, not programming really) and if you still reproduce? It wasn't that half, take half of the remaining out. If you don't reproduce? It was in the half you took out, revert that change and comment out only half of the original half...repeat.

sagark1510 commented 2 years ago

@mikehardy I'll give it a try. Thank you.

shivam-kakkar commented 2 years ago

For anyone facing this issue, I was stuck on this for 3 days and the only file that you need to check in case of infinite loop login is AppDelegate.m. I had issues because I was using multiple social auths and also deep linking. Here's what fixed in my case. If you are using google login or any other social auths add an if condition for them too.

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
  if ([[FBSDKApplicationDelegate sharedInstance] application:application openURL:url options:options]) {
    return YES;
  }

  if ([RNGoogleSignin application:application openURL:url options:options]) {
    return YES;
  }

  if ([RCTLinkingManager application:application openURL:url options:options]) {
    return YES;
  }

  return NO;
}
hugoh59 commented 1 year ago

I have the same issue but only on Android; works fine on iOS. I created an issue about it here https://github.com/thebergamo/react-native-fbsdk-next/issues/391

mladen4 commented 1 year ago

Same problem on android simulator, expo48. Method LoginManager.logInWithPermissions(["public_profile", "user_friends", "email"]) never resolve. No error on catch method. IOS is working fine.

mladen4 commented 1 year ago

Here is my dependencies: "dependencies": { "@babel/preset-typescript": "^7.18.6", "@react-native-community/art": "^1.2.0", "@react-native-community/viewpager": "5.0.11", "common": "1.0.0", "deprecated-react-native-prop-types": "^4.0.0", "expo": "^48.0.0", "expo-apple-authentication": "~6.0.1", "expo-av": "~13.2.1", "expo-device": "~5.2.1", "expo-firebase-analytics": "~8.0.0", "expo-font": "~11.1.1", "expo-in-app-purchases": "~14.1.1", "expo-keep-awake": "~12.0.1", "expo-linear-gradient": "~12.1.2", "expo-linking": "~4.0.1", "expo-secure-store": "~12.1.1", "expo-store-review": "~6.2.1", "expo-updates": "~0.16.4", "mobx": "^5.8.0", "mobx-react": "5.4.3", "node-libs-react-native": "^1.0.3", "react": "18.2.0", "react-dom": "18.2.0", "react-i18next": "9.0.8", "react-native": "0.71.3", "react-native-animate-number": "^0.1.2", "react-native-confetti": "0.1.0", "react-native-fbsdk-next": "^11.1.0", "react-native-gesture-handler": "~2.9.0", "react-native-google-mobile-ads": "^8.2.2", "react-native-particles": "^0.0.8", "react-native-progress": "^5.0.0", "react-native-progress-circle": "^2.1.0", "react-native-reanimated": "~2.14.4", "react-native-redash": "^14.1.1", "react-native-responsive-screen": "^1.4.1", "react-native-root-toast": "^3.3.0", "react-native-star-rating": "^1.1.0", "react-native-svg": "13.4.0", "react-native-svg-charts": "5.3.0", "react-native-swipe-gestures": "^1.0.5", "react-test-renderer": "18.0.0" }, "devDependencies": { "@babel/core": "^7.20.0", "@babel/plugin-proposal-class-properties": "^7.18.6", "@babel/plugin-proposal-decorators": "^7.20.13", "@types/react": "~18.0.27", "@types/react-native": "~0.70.6", "babel-jest": "~25.2.6", "babel-plugin-module-resolver": "^5.0.0", "babel-preset-expo": "^9.3.0", "expo-yarn-workspaces": "^2.0.0", "jest": "^29.2.1", "react-test-renderer": "18.0.0" },

michalis-ligopsychakis commented 1 year ago

Same issue here! I have tried this solution but didn't work.

I know that the "onActivityResult" is deprecated, but even with the new way here I'm facing the same issue.

I'm using react-native@0.64.4 and react-native-fbsdk@3.0.0 Any help is welcome :)

abdulbari149 commented 8 months ago

Facing the same issue. What should I do? I'm a bit newer to react-native

Jamon-code commented 6 months ago

Hello, A tutorial that currently works (as of 27/04/2027) can be found here. However, for those reading this in the future, the idea is to follow the most recent tutorial available. Over time, versions change, and so does code and tutorials.