Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🔥[🐛] [SOLVED v11.1.2] react-native 0.64 compatibility (was database TypeError: _SharedEventEmitter.default.once is not a function) #5027

Closed
2 of 10 tasks
brandonpearcy opened this issue Mar 14, 2021 · 10 comments · Fixed by #5042
Labels
help: needs-triage Issue needs additional investigation/triaging. type: bug New bug report

Comments

@brandonpearcy
Copy link

brandonpearcy commented Mar 14, 2021

Issue

After updating react-native from 0.63.4 to 0.64.0, calls to realtime database's Reference.on throw a run-time TypeError:

 ERROR  TypeError: _SharedEventEmitter.default.once is not a function. (In '_SharedEventEmitter.default.once(eventRegistrationKey, this._onOnceRemoveRegistration(eventRegistrationKey, listener))', '_SharedEventEmitter.default.once' is undefined)

It appears that commenting out the cancelCallbackOrContext parameter prevents the TypeError from being thrown, so there's something strange going on there. Looking at the TS type definition for on, it looks like the type for cancelCallbackOrContext doesn't match what I would expect. I would have expected it to be (e: Error) => void | Record<string, any> instead of Record<string, any>

Example min repro code:

import React, {useEffect} from 'react';
import type {Node} from 'react';
import database from '@react-native-firebase/database'
const App: () => Node = () => {
  useEffect(() => {
    database().ref('/communityProfiles/654321').on(
      'value',
        snapshot => console.log('snapshot', snapshot?.val()),
        error=> console.log('error', error) // <== comment out this line, and error goes away
    )
  }, [])
  return null
}
export default App;

Project Files

Javascript

Click To Expand

package.json:

{
  "name": "ReactNative64FirebaseRepro",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint ."
  },
  "dependencies": {
    "@react-native-firebase/app": "^11.1.0",
    "@react-native-firebase/database": "^11.1.0",
    "react": "17.0.1",
    "react-native": "0.64.0"
  },
  "devDependencies": {
    "@babel/core": "^7.13.10",
    "@babel/runtime": "^7.13.10",
    "@react-native-community/eslint-config": "^2.0.0",
    "babel-jest": "^26.6.3",
    "eslint": "^7.22.0",
    "jest": "^26.6.3",
    "metro-react-native-babel-preset": "^0.65.2",
    "react-test-renderer": "17.0.1"
  },
  "jest": {
    "preset": "react-native"
  }
}

firebase.json for react-native-firebase v6:

# N/A

iOS

Click To Expand

ios/Podfile:

  • I'm not using Pods
  • I'm using Pods and my Podfile looks like:
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

platform :ios, '10.0'

target 'ReactNative64FirebaseRepro' do
  config = use_native_modules!

  use_react_native!(
    :path => config[:reactNativePath],
    # to enable hermes on iOS, change `false` to `true` and then install pods
    :hermes_enabled => false
  )

  target 'ReactNative64FirebaseReproTests' do
    inherit! :complete
    # Pods for testing
  end

  # Enables Flipper.
  #
  # Note that if you have use_frameworks! enabled, Flipper will not work and
  # you should disable the next line.
  use_flipper!()

  post_install do |installer|
    react_native_post_install(installer)
  end
end```

#### `AppDelegate.m`:

```objc
#import "AppDelegate.h"

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>

#import <Firebase.h>

#ifdef FB_SONARKIT_ENABLED
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
#import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
#import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
#import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
#import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>

static void InitializeFlipper(UIApplication *application) {
  FlipperClient *client = [FlipperClient sharedClient];
  SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
  [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
  [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
  [client addPlugin:[FlipperKitReactPlugin new]];
  [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
  [client start];
}
#endif

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
#ifdef FB_SONARKIT_ENABLED
  InitializeFlipper(application);
#endif
  if ([FIRApp defaultApp] == nil) {
    [FIRApp configure];
  }

  RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
  RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
                                                   moduleName:@"ReactNative64FirebaseRepro"
                                            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 [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}

@end


Android

Click To Expand

Have you converted to AndroidX?

  • my application is an AndroidX application?
  • I am using android/gradle.settings jetifier=true for Android compatibility?
  • I am using the NPM package jetifier for react-native compatibility?

android/build.gradle:

// N/A

android/app/build.gradle:

// N/A

android/settings.gradle:

// N/A

MainApplication.java:

// N/A

AndroidManifest.xml:

<!-- N/A -->


Environment

Click To Expand

react-native info output:

System:
    OS: macOS 11.2
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 66.00 MB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 12.20.2 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/local/bin/yarn
    npm: 6.14.11 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.10.1 - /usr/local/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 14.4, DriverKit 20.2, macOS 11.1, tvOS 14.3, watchOS 7.2
    Android SDK: Not Found
  IDEs:
    Android Studio: 3.4 AI-183.6156.11.34.5692245
    Xcode: 12.4/12D4e - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.1 - /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
  • Platform that you're experiencing the issue on:
    • iOS
    • Android
    • iOS but have not tested behavior on Android
    • Android but have not tested behavior on iOS
    • Both
  • react-native-firebase version you're using that has this issue:
    • 11.1.0
  • Firebase module(s) you're using that has the issue:
    • database
  • Are you using TypeScript?
    • N & ``


@brandonpearcy brandonpearcy added help: needs-triage Issue needs additional investigation/triaging. type: bug New bug report labels Mar 14, 2021
@mikehardy
Copy link
Collaborator

Very strange - but it worked before (in react-native < 0.64?)
Looks related to this item:

For now it's clear react-native-firebase is not compatible with react-native 0.64.
We'll need to think about how to handle this to minimize disruption.

@mikehardy mikehardy changed the title 🔥[🐛] TypeError: _SharedEventEmitter.default.once is not a function 🔥[🐛] react-native 0.64 compatibility (was database TypeError: _SharedEventEmitter.default.once is not a function) Mar 14, 2021
@mikehardy mikehardy pinned this issue Mar 14, 2021
@mikehardy
Copy link
Collaborator

Note that a successful fix must also make sure types are in harmony with firebase-js-sdk where possible as mentioned by @brandonpearcy

@mikehardy
Copy link
Collaborator

For anyone following along, this also affects auth APIs and probably many others, I'm working on this now, but I mention this so that people don't mistakenly think it is database specific, it is a forward-porting need across the entire react-native-firebase package


  1) auth() => Phone
       verifyPhoneNumber
         successfully verifies:
     TypeError: this._auth.emitter.once is not a function

@mikehardy
Copy link
Collaborator

mikehardy commented Mar 17, 2021

Got lucky-ish, turns out it was just those two (database and auth) that were using the API removed in the react-native 0.64 breaking changes.

Not so bad: c2de179

I posted a PR that I'm 99% handles the forward-port of the library correctly, and if anyone could test it you can just pull the patch-package zip that we make for all PRs from the artifacts list on the Github Actions run: https://github.com/invertase/react-native-firebase/pull/5042/checks?check_run_id=2126589516

It may take another day or so to get the test app fully working with react-native 0.64 and I don't want to merge the forward port without either

a) hearing confirmation that it is working for people or
b) I've got the test app working and confirming it in the clean CI environment

So feedback will be welcome and might speed things up so everyone can start using hermes ;-)

Cheers

@brandonpearcy
Copy link
Author

@mikehardy It worked for us! 🚀🔥 🥳 🙌
I just had to apply the patches with patch-package, upgrade to react-native-firebase 11.1.1 and reinstall pods.

Huge thanks for tackling this so quickly. We all really appreciate it!

@mikehardy
Copy link
Collaborator

Great to hear, thank you. CI actually passed on iOS and Android with the non-Hermes engines so this may be ready for release - using those patches at least should be fine and patch-package is great of course, it'll let you know when it's time to evict them. Hermes should be fine if you intend to use it but that's a new thing so be sure to test if so. Cheers

@mikehardy
Copy link
Collaborator

Okay, the javascript code is working now, I still need to investigate the types though, here's our standard (firebase-js-sdk):

https://github.com/firebase/firebase-js-sdk/blob/3a465b40496cb18747e540f569f8340097009b04/packages/database-types/index.d.ts#L80-L97

I don't want to use Object (that's the Record<string, any> bit we have), but you are correct that there should be a union of type possibilities here. I'll patch that up.

mikehardy added a commit that referenced this issue Mar 17, 2021
This does not change the underlying implementation which should still be correct with
the updated types, it only copies in the type definitions from firebase-js-sdk so we
stay in sync with them

Related #5027 - the type-related part of that issue
@mikehardy
Copy link
Collaborator

I just posted a fix to the types file to close this out fully, v11.1.2 here should be released today, I'll just wait for CI to settle down first then hit the publish button.

Patches will show up here https://github.com/invertase/react-native-firebase/pull/5046/checks?check_run_id=2133507792 and I think will include the react-native 0.64 forward port plus the type fix, as the patches are generated from "latest published" version and the types PR is based on the RN64 work

mikehardy added a commit that referenced this issue Mar 17, 2021
This does not change the underlying implementation which should still be correct with
the updated types, it only copies in the type definitions from firebase-js-sdk so we
stay in sync with them

Related #5027 - the type-related part of that issue
@mikehardy mikehardy changed the title 🔥[🐛] react-native 0.64 compatibility (was database TypeError: _SharedEventEmitter.default.once is not a function) 🔥[🐛] [SOLVED v11.1.2] react-native 0.64 compatibility (was database TypeError: _SharedEventEmitter.default.once is not a function) Mar 17, 2021
@mikehardy mikehardy unpinned this issue Apr 10, 2021
@muzzamil76
Copy link

@mikehardy This is not fixed please check!

@muzzamil76
Copy link

@mikehardy i have raised the new ticket for this !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help: needs-triage Issue needs additional investigation/triaging. type: bug New bug report
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants