Skip to content

Commit 2ae886c

Browse files
committed
this should fix the crash on andorid
1 parent 7bda1f8 commit 2ae886c

File tree

6 files changed

+143
-11
lines changed

6 files changed

+143
-11
lines changed

android/src/main/java/com/facebook/reactnative/androidsdk/FBLoginButtonManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ public String getName() {
4949

5050
@Override
5151
public RCTLoginButton createViewInstance(ThemedReactContext context) {
52-
return new RCTLoginButton(context, mActivityEventListener.getCallbackManager());
52+
RCTLoginButton loginButton = new RCTLoginButton(context, mActivityEventListener.getCallbackManager());
53+
return loginButton;
5354
}
5455

5556
@ReactProp(name = "loginBehaviorAndroid")

android/src/main/java/com/facebook/reactnative/androidsdk/RCTLoginButton.java

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ public RCTLoginButton(ThemedReactContext context, CallbackManager callbackManage
4949
super(context);
5050
this.setToolTipMode(ToolTipMode.NEVER_DISPLAY);
5151
mCallbackManager = callbackManager;
52-
mEventDispatcher = UIManagerHelper.getEventDispatcherForReactTag((ReactContext) getContext(), getId());
52+
// Don't initialize EventDispatcher here - it will be null until the view is mounted
53+
mEventDispatcher = null;
5354
init();
5455
}
5556

@@ -62,9 +63,7 @@ protected void onCurrentAccessTokenChanged(
6263
if (currentAccessToken == null) {
6364
WritableMap event = Arguments.createMap();
6465
event.putString("type", "logoutFinished");
65-
ReactContext context = (ReactContext) getContext();
66-
mEventDispatcher.dispatchEvent(new RCTLoginButtonEvent(UIManagerHelper.getSurfaceId(context), getId(), event));
67-
66+
dispatchEvent(event);
6867
}
6968
}
7069
};
@@ -85,8 +84,7 @@ public void onSuccess(LoginResult loginResult) {
8584
Arguments.fromJavaArgs(
8685
setToStringArray(loginResult.getRecentlyDeniedPermissions())));
8786
event.putMap("result", result);
88-
ReactContext context = (ReactContext) getContext();
89-
mEventDispatcher.dispatchEvent(new RCTLoginButtonEvent(UIManagerHelper.getSurfaceId(context), getId(), event));
87+
dispatchEvent(event);
9088
}
9189

9290
@Override
@@ -97,8 +95,7 @@ public void onError(FacebookException error) {
9795
WritableMap result = Arguments.createMap();
9896
result.putBoolean("isCancelled", false);
9997
event.putMap("result", result);
100-
ReactContext context = (ReactContext) getContext();
101-
mEventDispatcher.dispatchEvent(new RCTLoginButtonEvent(UIManagerHelper.getSurfaceId(context), getId(), event));
98+
dispatchEvent(event);
10299
}
103100

104101
@Override
@@ -109,8 +106,7 @@ public void onCancel() {
109106
WritableMap result = Arguments.createMap();
110107
result.putBoolean("isCancelled", true);
111108
event.putMap("result", result);
112-
ReactContext context = (ReactContext) getContext();
113-
mEventDispatcher.dispatchEvent(new RCTLoginButtonEvent(UIManagerHelper.getSurfaceId(context), getId(), event));
109+
dispatchEvent(event);
114110
}
115111
});
116112
}
@@ -123,4 +119,33 @@ private String[] setToStringArray(Set<String> set) {
123119
}
124120
return array;
125121
}
122+
123+
public void initializeEventDispatcher() {
124+
if (mEventDispatcher == null) {
125+
ReactContext context = (ReactContext) getContext();
126+
// Only try to get the EventDispatcher if we have a valid ID
127+
if (getId() != -1) {
128+
mEventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(context, getId());
129+
}
130+
}
131+
}
132+
133+
private void dispatchEvent(WritableMap event) {
134+
initializeEventDispatcher();
135+
if (mEventDispatcher != null && getId() != -1 && isAttachedToWindow()) {
136+
ReactContext context = (ReactContext) getContext();
137+
try {
138+
mEventDispatcher.dispatchEvent(new RCTLoginButtonEvent(UIManagerHelper.getSurfaceId(context), getId(), event));
139+
} catch (Exception e) {
140+
// Silently handle any remaining edge cases to prevent crashes
141+
android.util.Log.w("RCTLoginButton", "Failed to dispatch event: " + e.getMessage());
142+
}
143+
}
144+
}
145+
146+
@Override
147+
protected void onAttachedToWindow() {
148+
super.onAttachedToWindow();
149+
initializeEventDispatcher();
150+
}
126151
}

package.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,14 @@
137137
"parser": "typescript"
138138
},
139139
"react-native": "src/index.ts",
140+
"codegenConfig": {
141+
"name": "RNFBSDKSpec",
142+
"type": "components",
143+
"jsSrcsDir": "src/specs",
144+
"android": {
145+
"javaPackageName": "com.facebook.reactnative.androidsdk"
146+
}
147+
},
140148
"react-native-builder-bob": {
141149
"source": "src",
142150
"output": "lib",
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
*/
9+
10+
import type {ViewProps} from 'react-native';
11+
import type {HostComponent} from 'react-native';
12+
import type {DirectEventHandler} from 'react-native/Libraries/Types/CodegenTypes';
13+
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
14+
15+
interface LoginFinishedEvent {
16+
readonly type: string;
17+
readonly error?: string;
18+
readonly result?: {
19+
readonly isCancelled: boolean;
20+
readonly grantedPermissions?: ReadonlyArray<string>;
21+
readonly declinedPermissions?: ReadonlyArray<string>;
22+
};
23+
}
24+
25+
interface NativeProps extends ViewProps {
26+
// Props
27+
permissions?: ReadonlyArray<string>;
28+
defaultAudience?: string;
29+
loginBehaviorAndroid?: string;
30+
tooltipBehaviorIOS?: string;
31+
nonceIOS?: string;
32+
loginTrackingIOS?: string;
33+
34+
// Events
35+
onChange?: DirectEventHandler<LoginFinishedEvent>;
36+
}
37+
38+
export default codegenNativeComponent<NativeProps>('RCTFBLoginButton') as HostComponent<NativeProps>;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
*/
9+
10+
import type {ViewProps} from 'react-native';
11+
import type {HostComponent} from 'react-native';
12+
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
13+
14+
interface ShareContent {
15+
readonly contentType: string;
16+
readonly contentUrl?: string;
17+
readonly contentTitle?: string;
18+
readonly contentDescription?: string;
19+
readonly imageUrl?: string;
20+
readonly peopleIds?: ReadonlyArray<string>;
21+
readonly placeId?: string;
22+
readonly ref?: string;
23+
}
24+
25+
interface NativeProps extends ViewProps {
26+
// Props
27+
shareContent?: ShareContent;
28+
}
29+
30+
export default codegenNativeComponent<NativeProps>('RCTFBSendButton') as HostComponent<NativeProps>;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
*/
9+
10+
import type {ViewProps} from 'react-native';
11+
import type {HostComponent} from 'react-native';
12+
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
13+
14+
interface ShareContent {
15+
readonly contentType: string;
16+
readonly contentUrl?: string;
17+
readonly contentTitle?: string;
18+
readonly contentDescription?: string;
19+
readonly imageUrl?: string;
20+
readonly peopleIds?: ReadonlyArray<string>;
21+
readonly placeId?: string;
22+
readonly ref?: string;
23+
}
24+
25+
interface NativeProps extends ViewProps {
26+
// Props
27+
shareContent?: ShareContent;
28+
}
29+
30+
export default codegenNativeComponent<NativeProps>('RCTFBShareButton') as HostComponent<NativeProps>;

0 commit comments

Comments
 (0)