Skip to content

Commit 713b229

Browse files
committed
fix(android): add TurboModule support for RNAppModule on RN 0.83+
This fixes the runtime crash "TurboModuleRegistry.getEnforcing(...): 'RNAppModule' not found" when using React Native 0.83+ with mandatory New Architecture. Changes: - Create NativeAppModule.ts TurboModule spec for Codegen - Update ReactNativeAppModule.java to extend NativeAppModuleSpec - Update GoogleMobileAdsNativeEventEmitter.ts to use TurboModule import - Enable isTurboModule flag for RNAppModule in Package.kt The RNAppModule (internal event handling module) was the only module not properly configured as a TurboModule. While other modules like RNGoogleMobileAdsModule had proper TurboModule support, RNAppModule extended ReactNativeModule (bridge-based) and had isTurboModule=false hardcoded in the package registration. Fixes #XXX
1 parent 618df9f commit 713b229

File tree

4 files changed

+82
-33
lines changed

4 files changed

+82
-33
lines changed

android/src/main/java/io/invertase/googlemobileads/ReactNativeAppModule.java

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*
1818
*/
1919

20+
import androidx.annotation.NonNull;
2021
import com.facebook.react.bridge.Promise;
2122
import com.facebook.react.bridge.ReactApplicationContext;
2223
import com.facebook.react.bridge.ReactMethod;
@@ -26,62 +27,54 @@
2627
import io.invertase.googlemobileads.common.ReactNativeEventEmitter;
2728
import io.invertase.googlemobileads.common.ReactNativeJSON;
2829
import io.invertase.googlemobileads.common.ReactNativeMeta;
29-
import io.invertase.googlemobileads.common.ReactNativeModule;
3030
import io.invertase.googlemobileads.common.ReactNativePreferences;
3131

32-
public class ReactNativeAppModule extends ReactNativeModule {
33-
static final String NAME = "RNAppModule";
32+
public class ReactNativeAppModule extends NativeAppModuleSpec {
33+
public static final String NAME = NativeAppModuleSpec.NAME;
3434

3535
ReactNativeAppModule(ReactApplicationContext reactContext) {
36-
super(reactContext, NAME);
36+
super(reactContext);
3737
}
3838

3939
@Override
4040
public void initialize() {
4141
super.initialize();
42-
ReactNativeEventEmitter.getSharedInstance().attachReactContext(getContext());
42+
ReactNativeEventEmitter.getSharedInstance().attachReactContext(getReactApplicationContext());
4343
}
4444

45+
@Override
4546
@ReactMethod
4647
public void initializeApp(ReadableMap options, ReadableMap appConfig, Promise promise) {
47-
// ReactNativeApp reactNativeApp =
48-
// RCTConvertFirebase.readableMapToFirebaseApp(options, appConfig, getContext());
49-
50-
// WritableMap reactNativeAppMap =
51-
// RCTConvertFirebase.reactNativeAppToWritableMap(reactNativeApp);
52-
// promise.resolve(reactNativeAppMap);
5348
promise.resolve(options);
5449
}
5550

51+
@Override
5652
@ReactMethod
57-
public void setAutomaticDataCollectionEnabled(String appName, Boolean enabled) {
58-
// ReactNativeApp reactNativeApp = ReactNativeApp.getInstance(appName);
59-
// reactNativeApp.setDataCollectionDefaultEnabled(enabled);
53+
public void setAutomaticDataCollectionEnabled(String appName, boolean enabled) {
54+
// No-op for ads module
6055
}
6156

57+
@Override
6258
@ReactMethod
6359
public void deleteApp(String appName, Promise promise) {
64-
// ReactNativeApp reactNativeApp = ReactNativeApp.getInstance(appName);
65-
66-
// if (reactNativeApp != null) {
67-
// reactNativeApp.delete();
68-
// }
69-
7060
promise.resolve(null);
7161
}
7262

63+
@Override
7364
@ReactMethod
74-
public void eventsNotifyReady(Boolean ready) {
65+
public void eventsNotifyReady(boolean ready) {
7566
ReactNativeEventEmitter emitter = ReactNativeEventEmitter.getSharedInstance();
7667
emitter.notifyJsReady(ready);
7768
}
7869

70+
@Override
7971
@ReactMethod
8072
public void eventsGetListeners(Promise promise) {
8173
ReactNativeEventEmitter emitter = ReactNativeEventEmitter.getSharedInstance();
8274
promise.resolve(emitter.getListenersMap());
8375
}
8476

77+
@Override
8578
@ReactMethod
8679
public void eventsPing(String eventName, ReadableMap eventBody, Promise promise) {
8780
ReactNativeEventEmitter emitter = ReactNativeEventEmitter.getSharedInstance();
@@ -90,58 +83,68 @@ public void eventsPing(String eventName, ReadableMap eventBody, Promise promise)
9083
promise.resolve(RCTConvert.readableMapToWritableMap(eventBody));
9184
}
9285

86+
@Override
9387
@ReactMethod
9488
public void eventsAddListener(String eventName) {
9589
ReactNativeEventEmitter emitter = ReactNativeEventEmitter.getSharedInstance();
9690
emitter.addListener(eventName);
9791
}
9892

93+
@Override
9994
@ReactMethod
100-
public void eventsRemoveListener(String eventName, Boolean all) {
95+
public void eventsRemoveListener(String eventName, boolean all) {
10196
ReactNativeEventEmitter emitter = ReactNativeEventEmitter.getSharedInstance();
10297
emitter.removeListener(eventName, all);
10398
}
10499

100+
@Override
105101
@ReactMethod
106102
public void addListener(String eventName) {
107103
// Keep: Required for RN built in Event Emitter Calls.
108104
}
109105

106+
@Override
110107
@ReactMethod
111-
public void removeListeners(Integer count) {
108+
public void removeListeners(double count) {
112109
// Keep: Required for RN built in Event Emitter Calls.
113110
}
114111

115112
/** ------------------ META ------------------ */
113+
@Override
116114
@ReactMethod
117115
public void metaGetAll(Promise promise) {
118116
promise.resolve(ReactNativeMeta.getSharedInstance().getAll());
119117
}
120118

121119
/** ------------------ JSON ------------------ */
120+
@Override
122121
@ReactMethod
123122
public void jsonGetAll(Promise promise) {
124123
promise.resolve(ReactNativeJSON.getSharedInstance().getAll());
125124
}
126125

127126
/** ------------------ PREFERENCES ------------------ */
127+
@Override
128128
@ReactMethod
129129
public void preferencesSetBool(String key, boolean value, Promise promise) {
130130
ReactNativePreferences.getSharedInstance().setBooleanValue(key, value);
131131
promise.resolve(null);
132132
}
133133

134+
@Override
134135
@ReactMethod
135136
public void preferencesSetString(String key, String value, Promise promise) {
136137
ReactNativePreferences.getSharedInstance().setStringValue(key, value);
137138
promise.resolve(null);
138139
}
139140

141+
@Override
140142
@ReactMethod
141143
public void preferencesGetAll(Promise promise) {
142144
promise.resolve(ReactNativePreferences.getSharedInstance().getAll());
143145
}
144146

147+
@Override
145148
@ReactMethod
146149
public void preferencesClearAll(Promise promise) {
147150
ReactNativePreferences.getSharedInstance().clearAll();

android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsPackage.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,11 @@ class ReactNativeGoogleMobileAdsPackage : TurboReactPackage() {
5757
moduleInfos[ReactNativeAppModule.NAME] =
5858
ReactModuleInfo(
5959
ReactNativeAppModule.NAME,
60-
ReactNativeAppModule.NAME,
60+
ReactNativeAppModule::class.java.name,
6161
false, // canOverrideExistingModule
6262
false, // needsEagerInit
6363
false, // isCxxModule
64-
false, // isTurboModule
64+
isTurboModule,
6565
)
6666
moduleInfos[ReactNativeGoogleMobileAdsModule.NAME] =
6767
ReactModuleInfo(

src/internal/GoogleMobileAdsNativeEventEmitter.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,10 @@
1515
*
1616
*/
1717

18-
import { NativeEventEmitter, NativeModules, NativeModule } from 'react-native';
18+
import { NativeEventEmitter } from 'react-native';
19+
import NativeAppModule from '../specs/modules/NativeAppModule';
1920

20-
type RNAppNativeModule = {
21-
eventsNotifyReady: (ready: boolean) => void;
22-
eventsAddListener: (eventType: string) => void;
23-
eventsRemoveListener: (eventType: string, FIXME: boolean) => void;
24-
} & NativeModule;
25-
26-
const RNAppModule = NativeModules.RNAppModule as RNAppNativeModule;
21+
const RNAppModule = NativeAppModule;
2722

2823
class GANativeEventEmitter extends NativeEventEmitter {
2924
ready: boolean;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (c) 2016-present Invertase Limited & Contributors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this library except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import type { TurboModule } from 'react-native';
18+
import { TurboModuleRegistry } from 'react-native';
19+
import type { UnsafeObject } from 'react-native/Libraries/Types/CodegenTypes';
20+
21+
export interface Spec extends TurboModule {
22+
// App initialization
23+
initializeApp(options: UnsafeObject, appConfig: UnsafeObject): Promise<UnsafeObject>;
24+
setAutomaticDataCollectionEnabled(appName: string, enabled: boolean): void;
25+
deleteApp(appName: string): Promise<void>;
26+
27+
// Events
28+
eventsNotifyReady(ready: boolean): void;
29+
eventsGetListeners(): Promise<UnsafeObject>;
30+
eventsPing(eventName: string, eventBody: UnsafeObject): Promise<UnsafeObject>;
31+
eventsAddListener(eventName: string): void;
32+
eventsRemoveListener(eventName: string, all: boolean): void;
33+
34+
// Required for RN built-in Event Emitter
35+
addListener(eventName: string): void;
36+
removeListeners(count: number): void;
37+
38+
// Meta
39+
metaGetAll(): Promise<UnsafeObject>;
40+
41+
// JSON
42+
jsonGetAll(): Promise<UnsafeObject>;
43+
44+
// Preferences
45+
preferencesSetBool(key: string, value: boolean): Promise<void>;
46+
preferencesSetString(key: string, value: string): Promise<void>;
47+
preferencesGetAll(): Promise<UnsafeObject>;
48+
preferencesClearAll(): Promise<void>;
49+
}
50+
51+
export default TurboModuleRegistry.getEnforcing<Spec>('RNAppModule');

0 commit comments

Comments
 (0)