@react-native-firebase/app 26.4.0 → 27.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +10 -27
  3. package/RNFBApp.podspec +13 -5
  4. package/android/build.gradle +3 -0
  5. package/android/src/main/java/io/invertase/firebase/common/RNFBHandleCollisionException.kt +29 -0
  6. package/android/src/main/java/io/invertase/firebase/common/RNFBHandleMap.kt +146 -0
  7. package/android/src/main/java/io/invertase/firebase/common/TaskExecutorService.kt +156 -0
  8. package/android/src/main/java/io/invertase/firebase/common/UniversalFirebaseModule.kt +44 -0
  9. package/android/src/main/java/io/invertase/firebase/common/UniversalFirebasePreferences.kt +100 -0
  10. package/android/src/reactnative/java/io/invertase/firebase/app/NativeRNFBTurboApp.kt +250 -0
  11. package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseApp.kt +64 -0
  12. package/android/src/reactnative/java/io/invertase/firebase/app/{ReactNativeFirebaseAppInitProvider.java → ReactNativeFirebaseAppInitProvider.kt} +3 -4
  13. package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseAppPackage.kt +47 -0
  14. package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseAppRegistrar.kt +33 -0
  15. package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseVersion.java +1 -1
  16. package/android/src/reactnative/java/io/invertase/firebase/common/RCTConvertFirebase.kt +185 -0
  17. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseEvent.kt +35 -0
  18. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitter.kt +662 -0
  19. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseJSON.kt +103 -0
  20. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseMeta.kt +96 -0
  21. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseModule.kt +140 -0
  22. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebasePreferences.kt +109 -0
  23. package/android/src/reactnative/java/io/invertase/firebase/common/SharedUtils.kt +451 -0
  24. package/android/src/reactnative/java/io/invertase/firebase/interfaces/{ContextProvider.java → ContextProvider.kt} +8 -8
  25. package/android/src/reactnative/java/io/invertase/firebase/interfaces/{NativeError.java → NativeError.kt} +8 -8
  26. package/android/src/reactnative/java/io/invertase/firebase/interfaces/{NativeEvent.java → NativeEvent.kt} +6 -6
  27. package/android/src/reactnative/java/io/invertase/firebase/utils/NativeRNFBTurboUtils.kt +219 -0
  28. package/android/src/test/java/expo/core/ModuleRegistry.java +9 -0
  29. package/android/src/test/java/io/invertase/firebase/app/NativeRNFBTurboAppTest.java +182 -59
  30. package/android/src/test/java/io/invertase/firebase/app/ReactNativeFirebaseAppComponentsJavaCompatibilityTest.java +70 -0
  31. package/android/src/test/java/io/invertase/firebase/app/ReactNativeFirebaseAppJavaCompatibilityTest.java +60 -0
  32. package/android/src/test/java/io/invertase/firebase/app/ReactNativeFirebaseAppPackageTest.java +165 -0
  33. package/android/src/test/java/io/invertase/firebase/app/ReactNativeFirebaseAppTest.kt +167 -0
  34. package/android/src/test/java/io/invertase/firebase/common/RCTConvertFirebaseJavaCompatibilityTest.java +112 -0
  35. package/android/src/test/java/io/invertase/firebase/common/RCTConvertFirebaseTest.kt +317 -0
  36. package/android/src/test/java/io/invertase/firebase/common/RNFBHandleMapTest.kt +309 -0
  37. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitterJavaCompatibilityTest.java +176 -0
  38. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitterTest.java +143 -12
  39. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseEventTest.kt +61 -0
  40. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseJSONJavaCompatibilityTest.java +85 -0
  41. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseJSONTest.kt +296 -0
  42. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseMetaJavaCompatibilityTest.java +67 -0
  43. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseMetaTest.kt +246 -0
  44. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseModuleTest.kt +254 -0
  45. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebasePreferencesJavaCompatibilityTest.java +87 -0
  46. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebasePreferencesTest.kt +260 -0
  47. package/android/src/test/java/io/invertase/firebase/common/SharedUtilsJavaCompatibilityTest.java +255 -0
  48. package/android/src/test/java/io/invertase/firebase/common/SharedUtilsTest.kt +674 -0
  49. package/android/src/test/java/io/invertase/firebase/common/TaskExecutorServiceTest.kt +290 -0
  50. package/android/src/test/java/io/invertase/firebase/common/UniversalFirebaseModuleJavaCompatibilityTest.java +178 -0
  51. package/android/src/test/java/io/invertase/firebase/common/UniversalFirebasePreferencesJavaCompatibilityTest.java +99 -0
  52. package/android/src/test/java/io/invertase/firebase/common/UniversalFirebasePreferencesTest.kt +217 -0
  53. package/android/src/test/java/io/invertase/firebase/commoncompat/ReactNativeFirebaseModuleJavaCompatibilityTest.java +176 -0
  54. package/android/src/test/java/io/invertase/firebase/commoncompat/ReactNativeFirebaseModuleKotlinCompatibilityTest.kt +52 -0
  55. package/android/src/test/java/io/invertase/firebase/interfaces/InterfacesJavaCompatibilityTest.java +144 -0
  56. package/android/src/test/java/io/invertase/firebase/interfaces/NativeEventTest.kt +56 -0
  57. package/android/src/test/java/io/invertase/firebase/utils/NativeRNFBTurboUtilsTest.java +517 -21
  58. package/dist/module/FirebaseApp.js +10 -0
  59. package/dist/module/FirebaseApp.js.map +1 -1
  60. package/dist/module/common/deeps.js +3 -0
  61. package/dist/module/common/deeps.js.map +1 -1
  62. package/dist/module/internal/FirebaseModule.js.map +1 -1
  63. package/dist/module/internal/RNFBNativeEventEmitter.js +12 -1
  64. package/dist/module/internal/RNFBNativeEventEmitter.js.map +1 -1
  65. package/dist/module/internal/SharedEventEmitter.js +3 -1
  66. package/dist/module/internal/SharedEventEmitter.js.map +1 -1
  67. package/dist/module/internal/index.js +1 -0
  68. package/dist/module/internal/index.js.map +1 -1
  69. package/dist/module/internal/registry/app.js +7 -1
  70. package/dist/module/internal/registry/app.js.map +1 -1
  71. package/dist/module/types/app.js.map +1 -1
  72. package/dist/module/types/internal.js +2 -0
  73. package/dist/module/version.js +1 -1
  74. package/dist/typescript/lib/FirebaseApp.d.ts +7 -0
  75. package/dist/typescript/lib/FirebaseApp.d.ts.map +1 -1
  76. package/dist/typescript/lib/common/deeps.d.ts.map +1 -1
  77. package/dist/typescript/lib/internal/FirebaseModule.d.ts +2 -3
  78. package/dist/typescript/lib/internal/FirebaseModule.d.ts.map +1 -1
  79. package/dist/typescript/lib/internal/NativeModules.d.ts +4 -1
  80. package/dist/typescript/lib/internal/NativeModules.d.ts.map +1 -1
  81. package/dist/typescript/lib/internal/RNFBNativeEventEmitter.d.ts +2 -2
  82. package/dist/typescript/lib/internal/RNFBNativeEventEmitter.d.ts.map +1 -1
  83. package/dist/typescript/lib/internal/SharedEventEmitter.d.ts +3 -3
  84. package/dist/typescript/lib/internal/SharedEventEmitter.d.ts.map +1 -1
  85. package/dist/typescript/lib/internal/index.d.ts +1 -0
  86. package/dist/typescript/lib/internal/index.d.ts.map +1 -1
  87. package/dist/typescript/lib/internal/registry/app.d.ts.map +1 -1
  88. package/dist/typescript/lib/types/app.d.ts +10 -3
  89. package/dist/typescript/lib/types/app.d.ts.map +1 -1
  90. package/dist/typescript/lib/types/internal.d.ts +12 -0
  91. package/dist/typescript/lib/types/internal.d.ts.map +1 -1
  92. package/dist/typescript/lib/version.d.ts +1 -1
  93. package/firebase-schema.json +4 -0
  94. package/firebase_spm.rb +552 -96
  95. package/ios/RNFBApp/RCTConvert+FIRApp.h +2 -5
  96. package/ios/RNFBApp/RCTConvert+FIRApp.m +11 -6
  97. package/ios/RNFBApp/RCTConvert+FIROptions.h +2 -5
  98. package/ios/RNFBApp/RCTConvert+FIROptions.m +11 -10
  99. package/ios/RNFBApp/RCTConvertFIRApp.swift +86 -0
  100. package/ios/RNFBApp/RCTConvertFIROptions.swift +259 -0
  101. package/ios/RNFBApp/RNFBAppCustomAuthDomains.swift +63 -0
  102. package/ios/RNFBApp/RNFBAppInitializeOptionsMapper.swift +113 -0
  103. package/ios/RNFBApp/RNFBAppLogLevelMapper.swift +53 -0
  104. package/ios/RNFBApp/RNFBAppModule+CustomAuthDomain.m +35 -0
  105. package/ios/RNFBApp/RNFBAppModule.h +6 -2
  106. package/ios/RNFBApp/RNFBAppModule.mm +65 -228
  107. package/ios/RNFBApp/RNFBAppModuleFirebase.swift +439 -0
  108. package/ios/RNFBApp/RNFBAppModuleImplementation.h +68 -0
  109. package/ios/RNFBApp/RNFBAppModuleImplementation.m +195 -0
  110. package/ios/RNFBApp/RNFBHandleMap.m +27 -56
  111. package/ios/RNFBApp/RNFBHandleMapStorage.swift +90 -0
  112. package/ios/RNFBApp/RNFBInitializeAppArguments.swift +82 -0
  113. package/ios/RNFBApp/RNFBJSON.m +22 -38
  114. package/ios/RNFBApp/RNFBJSONImplementation.swift +71 -0
  115. package/ios/RNFBApp/RNFBMeta.m +24 -26
  116. package/ios/RNFBApp/RNFBMetaStorage.swift +76 -0
  117. package/ios/RNFBApp/RNFBNullSentinelDecoding.swift +135 -0
  118. package/ios/RNFBApp/RNFBNullSentinelInterceptor.h +30 -3
  119. package/ios/RNFBApp/RNFBNullSentinelInterceptor.m +28 -5
  120. package/ios/RNFBApp/RNFBPreferences.m +22 -20
  121. package/ios/RNFBApp/RNFBPreferencesStorage.swift +101 -0
  122. package/ios/RNFBApp/RNFBRCTEventEmitter.m +36 -93
  123. package/ios/RNFBApp/RNFBRCTEventEmitterCore.swift +161 -0
  124. package/ios/RNFBApp/RNFBSharedUtils.h +2 -5
  125. package/ios/RNFBApp/RNFBSharedUtils.m +109 -198
  126. package/ios/RNFBApp/RNFBSharedUtilsConfig.swift +72 -0
  127. package/ios/RNFBApp/RNFBSharedUtilsFIRApp.swift +271 -0
  128. package/ios/RNFBApp/RNFBSharedUtilsFormatting.swift +59 -0
  129. package/ios/RNFBApp/RNFBSharedUtilsPromiseRejection.swift +88 -0
  130. package/ios/RNFBApp/RNFBUtilsHelpers.swift +116 -0
  131. package/ios/RNFBApp/RNFBUtilsModule+Foundation.m +44 -0
  132. package/ios/RNFBApp/RNFBUtilsModule+PhotoAssets.m +47 -0
  133. package/ios/RNFBApp/RNFBUtilsModule.h +11 -1
  134. package/ios/RNFBApp/RNFBUtilsModule.mm +10 -85
  135. package/ios/RNFBApp/RNFBUtilsModuleImplementation.h +32 -0
  136. package/ios/RNFBApp/RNFBUtilsModuleImplementation.m +56 -0
  137. package/ios/RNFBApp/RNFBVersion.m +1 -1
  138. package/ios/RNFBApp.xcodeproj/project.pbxproj +100 -0
  139. package/ios/RNFBAppUnitTests/HostStubs/FirebaseCore/FIRApp.m +171 -0
  140. package/ios/RNFBAppUnitTests/HostStubs/FirebaseCore/FirebaseCore.h +78 -0
  141. package/ios/RNFBAppUnitTests/HostStubs/FirebaseInstallations/FIRInstallations.m +7 -0
  142. package/ios/RNFBAppUnitTests/HostStubs/FirebaseInstallations/FirebaseInstallations.h +8 -0
  143. package/ios/RNFBAppUnitTests/HostStubs/RNFBAppModuleHostStub.m +55 -0
  144. package/ios/RNFBAppUnitTests/HostStubs/RNFBAppTurboModules.h +89 -0
  145. package/ios/RNFBAppUnitTests/HostStubs/RNFBAppTurboModules.mm +30 -0
  146. package/ios/RNFBAppUnitTests/HostStubs/React/RCTBridge.h +19 -0
  147. package/ios/RNFBAppUnitTests/HostStubs/React/RCTBridge.m +32 -0
  148. package/ios/RNFBAppUnitTests/HostStubs/React/RCTBridgeModule.h +19 -0
  149. package/ios/RNFBAppUnitTests/HostStubs/React/RCTConvert.h +28 -0
  150. package/ios/RNFBAppUnitTests/HostStubs/React/RCTConvert.m +23 -0
  151. package/ios/RNFBAppUnitTests/HostStubs/React/RCTEventEmitter.h +9 -0
  152. package/ios/RNFBAppUnitTests/HostStubs/React/RCTInvalidating.h +24 -0
  153. package/ios/RNFBAppUnitTests/HostStubs/React/RCTUtils.h +9 -0
  154. package/ios/RNFBAppUnitTests/HostStubs/module.modulemap +13 -0
  155. package/ios/RNFBAppUnitTests/RCTConvertFIRAppFacadeTests.m +61 -0
  156. package/ios/RNFBAppUnitTests/RCTConvertFIRAppTests.swift +73 -0
  157. package/ios/RNFBAppUnitTests/RCTConvertFIROptionsFacadeTests.m +57 -0
  158. package/ios/RNFBAppUnitTests/RCTConvertFIROptionsTests.swift +243 -0
  159. package/ios/RNFBAppUnitTests/RNFBAppCustomAuthDomainsFacadeTests.m +73 -0
  160. package/ios/RNFBAppUnitTests/RNFBAppCustomAuthDomainsTests.swift +70 -0
  161. package/ios/RNFBAppUnitTests/RNFBAppInitializeOptionsMapperTests.swift +190 -0
  162. package/ios/RNFBAppUnitTests/RNFBAppLogLevelFacadeTests.m +76 -0
  163. package/ios/RNFBAppUnitTests/RNFBAppLogLevelMapperTests.swift +59 -0
  164. package/ios/RNFBAppUnitTests/RNFBAppModuleFirebaseFacadeTests.m +215 -0
  165. package/ios/RNFBAppUnitTests/RNFBAppModuleFirebaseTests.swift +430 -0
  166. package/ios/RNFBAppUnitTests/RNFBAppModuleLifecycleTests.m +206 -0
  167. package/ios/RNFBAppUnitTests/RNFBAppModuleShellTests.mm +367 -0
  168. package/ios/RNFBAppUnitTests/RNFBAppUnitTests.xcodeproj/project.pbxproj +355 -2
  169. package/ios/RNFBAppUnitTests/RNFBFirebaseAppClientTests.swift +165 -0
  170. package/ios/RNFBAppUnitTests/RNFBHandleMapStorageTests.swift +121 -0
  171. package/ios/RNFBAppUnitTests/RNFBInitializeAppArgumentsTests.swift +256 -0
  172. package/ios/RNFBAppUnitTests/RNFBJSONImplementationTests.swift +126 -0
  173. package/ios/RNFBAppUnitTests/RNFBJSONTests.m +172 -0
  174. package/ios/RNFBAppUnitTests/RNFBMetaStorageTests.swift +106 -0
  175. package/ios/RNFBAppUnitTests/RNFBMetaTests.m +65 -0
  176. package/ios/RNFBAppUnitTests/RNFBNullSentinelDecodingTests.swift +286 -0
  177. package/ios/RNFBAppUnitTests/RNFBNullSentinelInterceptorTests.m +312 -0
  178. package/ios/RNFBAppUnitTests/RNFBPreferencesStorageTests.swift +105 -0
  179. package/ios/RNFBAppUnitTests/RNFBPreferencesTests.m +110 -0
  180. package/ios/RNFBAppUnitTests/RNFBRCTEventEmitterCoreTests.swift +163 -0
  181. package/ios/RNFBAppUnitTests/RNFBRCTEventEmitterFacadeTests.m +141 -0
  182. package/ios/RNFBAppUnitTests/RNFBSharedUtilsConfigFacadeTests.m +100 -0
  183. package/ios/RNFBAppUnitTests/RNFBSharedUtilsConfigTests.swift +234 -0
  184. package/ios/RNFBAppUnitTests/RNFBSharedUtilsFIRAppFacadeTests.m +145 -0
  185. package/ios/RNFBAppUnitTests/RNFBSharedUtilsFIRAppTests.swift +173 -0
  186. package/ios/RNFBAppUnitTests/RNFBSharedUtilsFormattingFacadeTests.m +38 -0
  187. package/ios/RNFBAppUnitTests/RNFBSharedUtilsFormattingTests.swift +82 -0
  188. package/ios/RNFBAppUnitTests/RNFBSharedUtilsNullSentinelTests.m +35 -0
  189. package/ios/RNFBAppUnitTests/RNFBSharedUtilsPromiseRejectionFacadeTests.m +107 -0
  190. package/ios/RNFBAppUnitTests/RNFBSharedUtilsPromiseRejectionTests.swift +133 -0
  191. package/ios/RNFBAppUnitTests/RNFBUtilsHelpersTests.swift +144 -0
  192. package/ios/RNFBAppUnitTests/RNFBUtilsModuleFacadeTests.m +72 -0
  193. package/ios/RNFBAppUnitTests/RNFBUtilsModuleShellTests.mm +282 -0
  194. package/ios/RNFBFirebase/Package.swift +53 -0
  195. package/ios/RNFBFirebase/Sources/RNFBFirebase/RNFBFirebase.swift +285 -0
  196. package/ios/RNFBFirebase/Sources/RNFBFirebaseBridge/Public/.gitkeep +0 -0
  197. package/ios/RNFBFirebase/Sources/RNFBFirebaseBridge/RNFBFirebaseBridge.m +169 -0
  198. package/ios/RNFBFirebase/Sources/RNFBFirebaseBridge/include/RNFBFirebaseBridge.h +52 -0
  199. package/ios/RNFBFirebaseUnitTests/RNFBAppDynamicFacadeTests.swift +240 -0
  200. package/{android/src/main/java/io/invertase/firebase/common/RNFBHandleCollisionException.java → ios/RNFBFirebaseUnitTests/RNFBFirebaseClientImport.swift} +23 -14
  201. package/ios/RNFBFirebaseUnitTests/RNFBFirebaseUnitTests.xcodeproj/project.pbxproj +588 -0
  202. package/ios/RNFBFirebaseUnitTests/RNFBFirebaseUnitTests.xcodeproj/xcshareddata/xcschemes/RNFBFirebaseUnitTests.xcscheme +83 -0
  203. package/ios_config.sh +50 -22
  204. package/lib/FirebaseApp.ts +10 -0
  205. package/lib/common/deeps.ts +3 -0
  206. package/lib/internal/FirebaseModule.ts +6 -3
  207. package/lib/internal/NativeModules.ts +4 -1
  208. package/lib/internal/RNFBNativeEventEmitter.ts +14 -5
  209. package/lib/internal/SharedEventEmitter.ts +5 -1
  210. package/lib/internal/index.ts +1 -0
  211. package/lib/internal/react-native-vendor-emitter.d.ts +11 -0
  212. package/lib/internal/registry/app.ts +7 -1
  213. package/lib/types/app.ts +10 -3
  214. package/lib/types/internal.ts +19 -0
  215. package/lib/version.ts +1 -1
  216. package/package.json +8 -8
  217. package/plugin/build/ios/appDelegate.js +2 -2
  218. package/plugin/build/ios/podfile.js +16 -16
  219. package/plugin/build/pluginConfig.d.ts +4 -2
  220. package/plugin/src/ios/appDelegate.ts +2 -2
  221. package/plugin/src/ios/podfile.ts +20 -23
  222. package/plugin/src/pluginConfig.ts +4 -2
  223. package/android/src/main/java/io/invertase/firebase/common/RNFBHandleMap.java +0 -150
  224. package/android/src/main/java/io/invertase/firebase/common/TaskExecutorService.java +0 -148
  225. package/android/src/main/java/io/invertase/firebase/common/UniversalFirebaseModule.java +0 -62
  226. package/android/src/main/java/io/invertase/firebase/common/UniversalFirebasePreferences.java +0 -91
  227. package/android/src/reactnative/java/io/invertase/firebase/app/NativeRNFBTurboApp.java +0 -224
  228. package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseApp.java +0 -46
  229. package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseAppPackage.java +0 -49
  230. package/android/src/reactnative/java/io/invertase/firebase/app/ReactNativeFirebaseAppRegistrar.java +0 -35
  231. package/android/src/reactnative/java/io/invertase/firebase/common/RCTConvertFirebase.java +0 -192
  232. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseEvent.java +0 -53
  233. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseEventEmitter.java +0 -606
  234. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseJSON.java +0 -109
  235. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseMeta.java +0 -101
  236. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebaseModule.java +0 -146
  237. package/android/src/reactnative/java/io/invertase/firebase/common/ReactNativeFirebasePreferences.java +0 -96
  238. package/android/src/reactnative/java/io/invertase/firebase/common/SharedUtils.java +0 -441
  239. package/android/src/reactnative/java/io/invertase/firebase/utils/NativeRNFBTurboUtils.java +0 -223
  240. package/android/src/test/java/io/invertase/firebase/common/RNFBHandleMapTest.java +0 -275
  241. package/android/src/test/java/io/invertase/firebase/common/ReactNativeFirebaseJSONTest.java +0 -108
  242. package/android/src/test/java/io/invertase/firebase/common/TaskExecutorServiceTest.java +0 -97
@@ -0,0 +1,290 @@
1
+ package io.invertase.firebase.common
2
+
3
+ /*
4
+ * Copyright (c) 2016-present Invertase Limited & Contributors
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this library except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ *
18
+ */
19
+
20
+ import org.json.JSONObject
21
+ import org.junit.After
22
+ import org.junit.Assert.assertEquals
23
+ import org.junit.Assert.assertFalse
24
+ import org.junit.Assert.assertNotSame
25
+ import org.junit.Assert.assertSame
26
+ import org.junit.Assert.assertTrue
27
+ import org.junit.Assert.fail
28
+ import org.junit.Before
29
+ import org.junit.Test
30
+ import org.mockito.ArgumentMatchers.anyInt
31
+ import org.mockito.ArgumentMatchers.anyString
32
+ import org.mockito.Mockito.mock
33
+ import org.mockito.Mockito.`when`
34
+ import java.util.Collections
35
+ import java.util.concurrent.CountDownLatch
36
+ import java.util.concurrent.ExecutorService
37
+ import java.util.concurrent.LinkedBlockingQueue
38
+ import java.util.concurrent.RejectedExecutionException
39
+ import java.util.concurrent.RejectedExecutionHandler
40
+ import java.util.concurrent.SynchronousQueue
41
+ import java.util.concurrent.ThreadPoolExecutor
42
+ import java.util.concurrent.TimeUnit
43
+ import java.util.concurrent.atomic.AtomicBoolean
44
+
45
+ /**
46
+ * Plain JUnit4 + Mockito (AndroidTest-AD-1). Constructor reads pool sizing from
47
+ * [ReactNativeFirebaseJSON]; stub that away so we never touch Android's unmocked
48
+ * `org.json.JSONObject`.
49
+ */
50
+ class TaskExecutorServiceTest {
51
+ private lateinit var jsonObjectField: java.lang.reflect.Field
52
+ private var originalJsonObject: Any? = null
53
+ private val configuration = HashMap<String, Int>()
54
+
55
+ @Before
56
+ fun setUp() {
57
+ val jsonObject = mock(JSONObject::class.java)
58
+ `when`(jsonObject.optInt(anyString(), anyInt()))
59
+ .thenAnswer { invocation ->
60
+ configuration[invocation.getArgument(0)] ?: invocation.getArgument(1)
61
+ }
62
+ val json = ReactNativeFirebaseJSON.getSharedInstance()
63
+ jsonObjectField = ReactNativeFirebaseJSON::class.java.getDeclaredField("jsonObject")
64
+ jsonObjectField.isAccessible = true
65
+ originalJsonObject = jsonObjectField.get(json)
66
+ jsonObjectField.set(json, jsonObject)
67
+ }
68
+
69
+ @After
70
+ fun tearDown() {
71
+ jsonObjectField.set(ReactNativeFirebaseJSON.getSharedInstance(), originalJsonObject)
72
+ configuration.clear()
73
+ }
74
+
75
+ @Test
76
+ fun transactionalExecutorRunsSubmittedWork() {
77
+ val service = TaskExecutorService("TestTransactionalRuns")
78
+ val executor = service.getTransactionalExecutor()
79
+ val latch = CountDownLatch(1)
80
+
81
+ executor.execute(latch::countDown)
82
+
83
+ assertTrue("work submitted before shutdown runs", latch.await(5, TimeUnit.SECONDS))
84
+ assertSame(executor, service.getExecutor())
85
+ service.shutdown()
86
+ }
87
+
88
+ @Test
89
+ fun transactionalExecutorIsSingleThreadedNonDaemonAndOrdered() {
90
+ val service = TaskExecutorService("TestTransactionalSemantics")
91
+ val executor = service.getTransactionalExecutor()
92
+ val firstStarted = CountDownLatch(1)
93
+ val releaseFirst = CountDownLatch(1)
94
+ val finished = CountDownLatch(2)
95
+ val order = Collections.synchronizedList(ArrayList<Int>())
96
+ var threadName = ""
97
+ var daemon = true
98
+
99
+ executor.execute {
100
+ threadName = Thread.currentThread().name
101
+ daemon = Thread.currentThread().isDaemon
102
+ order.add(1)
103
+ firstStarted.countDown()
104
+ releaseFirst.await()
105
+ finished.countDown()
106
+ }
107
+ assertTrue(firstStarted.await(5, TimeUnit.SECONDS))
108
+ executor.execute {
109
+ order.add(2)
110
+ finished.countDown()
111
+ }
112
+ assertEquals(listOf(1), order)
113
+ releaseFirst.countDown()
114
+
115
+ assertTrue(finished.await(5, TimeUnit.SECONDS))
116
+ assertEquals(listOf(1, 2), order)
117
+ assertTrue(threadName.matches(Regex("pool-\\d+-thread-1")))
118
+ assertFalse(daemon)
119
+ service.shutdown()
120
+ }
121
+
122
+ @Test
123
+ fun configuredPooledExecutorPreservesPoolSettingsAndFallbackExecution() {
124
+ configuration["android_task_executor_maximum_pool_size"] = 1
125
+ configuration["android_task_executor_keep_alive_seconds"] = 7
126
+ val service = TaskExecutorService("TestPooledFallback")
127
+ val executor = service.getExecutor(false, "") as ThreadPoolExecutor
128
+ val blockingStarted = CountDownLatch(1)
129
+ val releaseBlocking = CountDownLatch(1)
130
+ val fallbackRan = CountDownLatch(1)
131
+
132
+ executor.execute {
133
+ blockingStarted.countDown()
134
+ releaseBlocking.await()
135
+ }
136
+ assertTrue(blockingStarted.await(5, TimeUnit.SECONDS))
137
+ executor.execute(fallbackRan::countDown)
138
+
139
+ assertTrue(fallbackRan.await(5, TimeUnit.SECONDS))
140
+ assertEquals(0, executor.corePoolSize)
141
+ assertEquals(1, executor.maximumPoolSize)
142
+ assertEquals(7L, executor.getKeepAliveTime(TimeUnit.SECONDS))
143
+ assertTrue(executor.queue is SynchronousQueue<*>)
144
+ releaseBlocking.countDown()
145
+ service.shutdown()
146
+ }
147
+
148
+ @Test
149
+ fun defaultExecutorUsesConfiguredPoolWhenMaximumExceedsOne() {
150
+ configuration["android_task_executor_maximum_pool_size"] = 2
151
+ val service = TaskExecutorService("TestDefaultPool")
152
+
153
+ val executor = service.getExecutor() as ThreadPoolExecutor
154
+
155
+ assertEquals(0, executor.corePoolSize)
156
+ assertEquals(2, executor.maximumPoolSize)
157
+ assertTrue(executor.queue is SynchronousQueue<*>)
158
+ service.shutdown()
159
+ }
160
+
161
+ @Test
162
+ fun transactionalIdentifiersAreCachedAndDistinctWhenPoolingEnabled() {
163
+ val service = TaskExecutorService("TestIdentifiers")
164
+ val first = service.getTransactionalExecutor("one")
165
+
166
+ assertSame(first, service.getTransactionalExecutor("one"))
167
+ assertNotSame(first, service.getTransactionalExecutor("two"))
168
+ service.shutdown()
169
+ }
170
+
171
+ @Test
172
+ fun transactionalIdentifierIsIgnoredWhenPoolingDisabled() {
173
+ configuration["android_task_executor_maximum_pool_size"] = 0
174
+ val service = TaskExecutorService("TestZeroPool")
175
+
176
+ assertSame(
177
+ service.getTransactionalExecutor("one"),
178
+ service.getTransactionalExecutor("two"),
179
+ )
180
+ service.shutdown()
181
+ }
182
+
183
+ @Test
184
+ fun executorNamesPreserveTransactionalAndPooledShapes() {
185
+ val service = TaskExecutorService("TestNames")
186
+
187
+ assertEquals("TestNamesTransactionalExecutorid", service.getExecutorName(true, "id"))
188
+ assertEquals("TestNamesExecutorid", service.getExecutorName(false, "id"))
189
+ service.shutdown()
190
+ }
191
+
192
+ @Test
193
+ fun concurrentLookupReturnsOneSharedExecutor() {
194
+ val service = TaskExecutorService("TestConcurrentLookup")
195
+ val start = CountDownLatch(1)
196
+ val done = CountDownLatch(2)
197
+ val executors = Collections.synchronizedList(ArrayList<ExecutorService>())
198
+ val threads =
199
+ List(2) {
200
+ Thread {
201
+ start.await()
202
+ executors.add(service.getTransactionalExecutor())
203
+ done.countDown()
204
+ }
205
+ }
206
+
207
+ threads.forEach(Thread::start)
208
+ start.countDown()
209
+
210
+ assertTrue(done.await(5, TimeUnit.SECONDS))
211
+ assertSame(executors[0], executors[1])
212
+ service.shutdown()
213
+ }
214
+
215
+ @Test
216
+ fun removeExecutorShutsDownKnownExecutorAndIgnoresMissingName() {
217
+ val service = TaskExecutorService("TestRemove")
218
+ val executor = service.getTransactionalExecutor()
219
+
220
+ service.removeExecutor("missing")
221
+ assertFalse(executor.isShutdown)
222
+ service.removeExecutor(service.getExecutorName(true, ""))
223
+
224
+ assertTrue(executor.isShutdown)
225
+ }
226
+
227
+ @Test
228
+ fun shutdownShutsDownOwnExecutorsAndOnlyRemovesForeignMapping() {
229
+ val foreignService = TaskExecutorService("TestForeign")
230
+ val foreignExecutor = foreignService.getTransactionalExecutor()
231
+ val service = TaskExecutorService("TestShutdown")
232
+ val ownExecutor = service.getTransactionalExecutor()
233
+
234
+ service.shutdown()
235
+
236
+ assertTrue(ownExecutor.isShutdown)
237
+ assertFalse(foreignExecutor.isShutdown)
238
+ assertNotSame(foreignExecutor, foreignService.getTransactionalExecutor())
239
+ foreignExecutor.shutdownNow()
240
+ foreignService.shutdown()
241
+ }
242
+
243
+ @Test
244
+ fun transactionalExecutorUsesUnboundedQueueAndAbortSemanticsBeforeShutdown() {
245
+ val service = TaskExecutorService("TestTransactionalShape")
246
+ val executor = service.getTransactionalExecutor() as ThreadPoolExecutor
247
+
248
+ assertEquals(1, executor.corePoolSize)
249
+ assertEquals(1, executor.maximumPoolSize)
250
+ assertTrue(executor.queue is LinkedBlockingQueue<*>)
251
+
252
+ val field = TaskExecutorService::class.java.getDeclaredField("discardAfterShutdown")
253
+ field.isAccessible = true
254
+ val handler = field.get(null) as RejectedExecutionHandler
255
+ try {
256
+ handler.rejectedExecution({}, executor)
257
+ fail("expected RejectedExecutionException")
258
+ } catch (exception: RejectedExecutionException) {
259
+ assertTrue(exception.message!!.contains("rejected from"))
260
+ }
261
+ service.shutdown()
262
+ }
263
+
264
+ @Test
265
+ fun transactionalExecutorDiscardsWorkSubmittedAfterShutdown() {
266
+ val service = TaskExecutorService("TestTransactionalShutdown")
267
+ val executor = service.getTransactionalExecutor()
268
+ service.shutdown()
269
+ val ran = AtomicBoolean(false)
270
+
271
+ // Must not throw RejectedExecutionException - this is the crash path hit when a
272
+ // play-services Task completes after module invalidation has shut the executor down.
273
+ executor.execute { ran.set(true) }
274
+
275
+ assertFalse("work submitted after shutdown is discarded", ran.get())
276
+ }
277
+
278
+ @Test
279
+ fun pooledExecutorDiscardsWorkSubmittedAfterShutdown() {
280
+ val service = TaskExecutorService("TestPooledShutdown")
281
+ val executor = service.getExecutor(false, "")
282
+ service.shutdown()
283
+ val ran = AtomicBoolean(false)
284
+
285
+ // Exercises the executeInFallback handler's shutdown guard.
286
+ executor.execute { ran.set(true) }
287
+
288
+ assertFalse("work submitted after shutdown is discarded", ran.get())
289
+ }
290
+ }
@@ -0,0 +1,178 @@
1
+ package io.invertase.firebase.common;
2
+
3
+ /*
4
+ * Copyright (c) 2016-present Invertase Limited & Contributors
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this library except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ import static org.junit.Assert.assertEquals;
20
+ import static org.junit.Assert.assertFalse;
21
+ import static org.junit.Assert.assertNotSame;
22
+ import static org.junit.Assert.assertNull;
23
+ import static org.junit.Assert.assertSame;
24
+ import static org.junit.Assert.assertThrows;
25
+ import static org.junit.Assert.assertTrue;
26
+ import static org.mockito.Mockito.mock;
27
+ import static org.mockito.Mockito.when;
28
+
29
+ import android.content.Context;
30
+ import java.lang.reflect.Constructor;
31
+ import java.lang.reflect.Field;
32
+ import java.lang.reflect.Method;
33
+ import java.lang.reflect.Modifier;
34
+ import java.util.Arrays;
35
+ import java.util.HashMap;
36
+ import java.util.Map;
37
+ import java.util.concurrent.ExecutorService;
38
+ import javax.annotation.OverridingMethodsMustInvokeSuper;
39
+ import org.json.JSONObject;
40
+ import org.junit.After;
41
+ import org.junit.Before;
42
+ import org.junit.Test;
43
+
44
+ /** Verifies the Kotlin port remains source- and binary-compatible with Java callers. */
45
+ public class UniversalFirebaseModuleJavaCompatibilityTest {
46
+ private Field jsonObjectField;
47
+ private Object originalJsonObject;
48
+
49
+ @Before
50
+ public void setUp() throws Exception {
51
+ ReactNativeFirebaseJSON json = ReactNativeFirebaseJSON.getSharedInstance();
52
+ jsonObjectField = ReactNativeFirebaseJSON.class.getDeclaredField("jsonObject");
53
+ jsonObjectField.setAccessible(true);
54
+ originalJsonObject = jsonObjectField.get(json);
55
+ jsonObjectField.set(json, mock(JSONObject.class));
56
+ }
57
+
58
+ @After
59
+ public void tearDown() throws Exception {
60
+ jsonObjectField.set(ReactNativeFirebaseJSON.getSharedInstance(), originalJsonObject);
61
+ }
62
+
63
+ @Test
64
+ public void preservesPublicOpenJavaAbi() throws Exception {
65
+ Class<UniversalFirebaseModule> type = UniversalFirebaseModule.class;
66
+ Constructor<UniversalFirebaseModule> constructor =
67
+ type.getConstructor(Context.class, String.class);
68
+
69
+ assertTrue(Modifier.isPublic(type.getModifiers()));
70
+ assertFalse(Modifier.isFinal(type.getModifiers()));
71
+ assertTrue(Modifier.isPublic(constructor.getModifiers()));
72
+
73
+ for (String methodName :
74
+ Arrays.asList(
75
+ "getContext",
76
+ "getApplicationContext",
77
+ "getExecutor",
78
+ "getName",
79
+ "onTearDown",
80
+ "getConstants")) {
81
+ Method method = type.getDeclaredMethod(methodName);
82
+ assertTrue(methodName, Modifier.isPublic(method.getModifiers()));
83
+ assertFalse(methodName, Modifier.isFinal(method.getModifiers()));
84
+ }
85
+
86
+ assertEquals(Context.class, type.getDeclaredMethod("getContext").getReturnType());
87
+ assertEquals(Context.class, type.getDeclaredMethod("getApplicationContext").getReturnType());
88
+ assertEquals(ExecutorService.class, type.getDeclaredMethod("getExecutor").getReturnType());
89
+ assertEquals(String.class, type.getDeclaredMethod("getName").getReturnType());
90
+ assertEquals(void.class, type.getDeclaredMethod("onTearDown").getReturnType());
91
+ assertEquals(Map.class, type.getDeclaredMethod("getConstants").getReturnType());
92
+ assertTrue(
93
+ type.getDeclaredMethod("onTearDown")
94
+ .isAnnotationPresent(OverridingMethodsMustInvokeSuper.class));
95
+ }
96
+
97
+ @Test
98
+ public void preservesNullPermissivenessNameAndContextBehavior() {
99
+ UniversalFirebaseModule nullModule = new UniversalFirebaseModule(null, null);
100
+
101
+ assertNull(nullModule.getContext());
102
+ assertEquals("UniversalnullModule", nullModule.getName());
103
+ assertThrows(NullPointerException.class, nullModule::getApplicationContext);
104
+ nullModule.onTearDown();
105
+
106
+ Context context = mock(Context.class);
107
+ Context applicationContext = mock(Context.class);
108
+ when(context.getApplicationContext()).thenReturn(applicationContext);
109
+ UniversalFirebaseModule module = new UniversalFirebaseModule(context, "App");
110
+
111
+ assertSame(context, module.getContext());
112
+ assertSame(applicationContext, module.getApplicationContext());
113
+ assertEquals("UniversalAppModule", module.getName());
114
+ module.onTearDown();
115
+
116
+ Context contextWithNoApplicationContext = mock(Context.class);
117
+ UniversalFirebaseModule nullApplicationContextModule =
118
+ new UniversalFirebaseModule(contextWithNoApplicationContext, "NullApplicationContext");
119
+ assertNull(nullApplicationContextModule.getApplicationContext());
120
+ nullApplicationContextModule.onTearDown();
121
+ }
122
+
123
+ @Test
124
+ public void constructorUsesVirtualGetNameDuringSuperConstruction() throws Exception {
125
+ ConstructorDispatchModule module = new ConstructorDispatchModule(null, "Ignored");
126
+ Field executorServiceField = UniversalFirebaseModule.class.getDeclaredField("executorService");
127
+ executorServiceField.setAccessible(true);
128
+ Object executorService = executorServiceField.get(module);
129
+ Field nameField = TaskExecutorService.class.getDeclaredField("name");
130
+ nameField.setAccessible(true);
131
+
132
+ assertEquals("DuringSuper", nameField.get(executorService));
133
+ assertEquals("AfterSuper", module.getName());
134
+ module.onTearDown();
135
+ }
136
+
137
+ @Test
138
+ public void exposesExecutorAndTearDownShutsItDown() {
139
+ UniversalFirebaseModule module = new UniversalFirebaseModule(null, "Shutdown");
140
+ ExecutorService executor = module.getExecutor();
141
+
142
+ assertSame(executor, module.getExecutor());
143
+ assertFalse(executor.isShutdown());
144
+
145
+ module.onTearDown();
146
+
147
+ assertTrue(executor.isShutdown());
148
+ }
149
+
150
+ @Test
151
+ public void constantsAreFreshMutableHashMaps() {
152
+ UniversalFirebaseModule module = new UniversalFirebaseModule(null, "Constants");
153
+ Map<String, Object> first = module.getConstants();
154
+ Map<String, Object> second = module.getConstants();
155
+
156
+ assertTrue(first instanceof HashMap);
157
+ assertTrue(second instanceof HashMap);
158
+ assertNotSame(first, second);
159
+ first.put("mutable", true);
160
+ assertEquals(true, first.get("mutable"));
161
+ assertTrue(second.isEmpty());
162
+ module.onTearDown();
163
+ }
164
+
165
+ private static final class ConstructorDispatchModule extends UniversalFirebaseModule {
166
+ private String state;
167
+
168
+ ConstructorDispatchModule(Context context, String serviceName) {
169
+ super(context, serviceName);
170
+ state = "AfterSuper";
171
+ }
172
+
173
+ @Override
174
+ public String getName() {
175
+ return state == null ? "DuringSuper" : state;
176
+ }
177
+ }
178
+ }
@@ -0,0 +1,99 @@
1
+ package io.invertase.firebase.common;
2
+
3
+ /*
4
+ * Copyright (c) 2016-present Invertase Limited & Contributors
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this library except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ import static org.junit.Assert.assertFalse;
20
+ import static org.junit.Assert.assertNull;
21
+ import static org.junit.Assert.assertSame;
22
+ import static org.mockito.Mockito.mock;
23
+ import static org.mockito.Mockito.never;
24
+ import static org.mockito.Mockito.times;
25
+ import static org.mockito.Mockito.verify;
26
+ import static org.mockito.Mockito.when;
27
+
28
+ import android.content.SharedPreferences;
29
+ import java.lang.reflect.Field;
30
+ import org.junit.Before;
31
+ import org.junit.Test;
32
+
33
+ /** Proves the Kotlin port preserves Java null calls and remove ownership. */
34
+ public class UniversalFirebasePreferencesJavaCompatibilityTest {
35
+ private SharedPreferences preferences;
36
+ private SharedPreferences.Editor editor;
37
+ private UniversalFirebasePreferences subject;
38
+
39
+ @Before
40
+ public void setUp() throws Exception {
41
+ preferences = mock(SharedPreferences.class);
42
+ editor = mock(SharedPreferences.Editor.class);
43
+ when(preferences.edit()).thenReturn(editor);
44
+ when(editor.putBoolean(null, true)).thenReturn(editor);
45
+ when(editor.putInt(null, 42)).thenReturn(editor);
46
+ when(editor.putLong(null, 4294967296L)).thenReturn(editor);
47
+ when(editor.putString(null, null)).thenReturn(editor);
48
+ when(editor.remove(null)).thenReturn(editor);
49
+ when(preferences.contains(null)).thenReturn(false);
50
+ when(preferences.getBoolean(null, true)).thenReturn(false);
51
+ when(preferences.getInt(null, 42)).thenReturn(42);
52
+ when(preferences.getLong(null, 4294967296L)).thenReturn(4294967296L);
53
+ when(preferences.getString(null, null)).thenReturn(null);
54
+
55
+ subject = new UniversalFirebasePreferences();
56
+ Field field = UniversalFirebasePreferences.class.getDeclaredField("preferences");
57
+ field.setAccessible(true);
58
+ field.set(subject, preferences);
59
+ }
60
+
61
+ @Test
62
+ public void publicAccessorsAcceptNullKeysFromJava() {
63
+ assertFalse(subject.contains(null));
64
+ subject.setBooleanValue(null, true);
65
+ assertFalse(subject.getBooleanValue(null, true));
66
+ subject.setIntValue(null, 42);
67
+ subject.getIntValue(null, 42);
68
+ subject.setLongValue(null, 4294967296L);
69
+ subject.getLongValue(null, 4294967296L);
70
+
71
+ verify(preferences).contains(null);
72
+ verify(editor).putBoolean(null, true);
73
+ verify(preferences).getBoolean(null, true);
74
+ verify(editor).putInt(null, 42);
75
+ verify(preferences).getInt(null, 42);
76
+ verify(editor).putLong(null, 4294967296L);
77
+ verify(preferences).getLong(null, 4294967296L);
78
+ verify(editor, times(3)).apply();
79
+ }
80
+
81
+ @Test
82
+ public void stringAccessorsAcceptNullsAndCanReturnNullToJava() {
83
+ subject.setStringValue(null, null);
84
+
85
+ assertNull(subject.getStringValue(null, null));
86
+ verify(editor).putString(null, null);
87
+ verify(editor).apply();
88
+ verify(preferences).getString(null, null);
89
+ }
90
+
91
+ @Test
92
+ public void removeAcceptsNullAndLeavesEditorCompletionToJavaCaller() {
93
+ assertSame(editor, subject.remove(null));
94
+
95
+ verify(editor).remove(null);
96
+ verify(editor, never()).apply();
97
+ verify(editor, never()).commit();
98
+ }
99
+ }