React-native-firebase: 🔥httpsCallable fails with "The data couldn't be read because it isn't in the correct format"

Created on 21 Oct 2019  ·  11Comments  ·  Source: invertase/react-native-firebase


Issue



Calling a cloud function fails with "The data couldn't be read because it isn't in the correct format" when using the emulator with firebase.functions().useFunctionsEmulator('http://localhost:5001');

Cloud function:

import * as functions from 'firebase-functions';

export const helloWorld = functions.https.onCall((input, context) => {
  return {message: 'hello world'};
});

RN App:

firebase.functions().useFunctionsEmulator('http://localhost:5001');

function MyComponent() {
  async function helloWorld() {
    try {
      await firebase.auth().signInAnonymously();
      const {data} = await firebase.functions().httpsCallable('helloWorld')();
      console.log(data);
    } catch (e) {
      console.error(e);
    }
  }
  useEffect(() => {
    helloWorld();
  }, []);
  return <View><Text>Test</Text></View>;
}

Project Files






iOS

Click To Expand

#### `ios/Podfile`: - [ ] I'm not using Pods - [x] I'm using Pods and my Podfile looks like:

platform :ios, '9.0'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'

target 'syllaballs' do
  # Pods for syllaballs
  pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector"
  pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec"
  pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired"
  pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety"
  pod 'React', :path => '../node_modules/react-native/'
  pod 'React-Core', :path => '../node_modules/react-native/'
  pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules'
  pod 'React-Core/DevSupport', :path => '../node_modules/react-native/'
  pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
  pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
  pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
  pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
  pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
  pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
  pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
  pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
  pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
  pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/'

  pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
  pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
  pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
  pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
  pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon"
  pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon"
  pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga'

  pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
  pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
  pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'

  pod 'FBSDKLoginKit'
  pod 'GoogleSignIn', '~> 5.0.0'

  pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'

  target 'syllaballsTests' do
    inherit! :search_paths
    # Pods for testing
  end

  use_native_modules!
end

target 'syllaballs-tvOS' do
  # Pods for syllaballs-tvOS

  target 'syllaballs-tvOSTests' do
    inherit! :search_paths
    # Pods for testing
  end

end

post_install do |pi|
  pi.pods_project.targets.each do |t|
    t.build_configurations.each do |config|
      config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0'
    end
  end
end
#### `AppDelegate.m`:
#import "AppDelegate.h"

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

#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <RNGoogleSignin/RNGoogleSignin.h>

@import Firebase;

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

#pragma mark - Set up default firebase app
  if ([FIRApp defaultApp] == nil) {
    [FIRApp configure];
  }
  [[FBSDKApplicationDelegate sharedInstance] application:application
                           didFinishLaunchingWithOptions:launchOptions];

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

  rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f
                                                    green:1.0f
                                                     blue:1.0f
                                                    alpha:1];

  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
}

#pragma mark - Handle incoming universal links
- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
            options:
                (NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {

  BOOL facebook = [[FBSDKApplicationDelegate sharedInstance]
            application:application
                openURL:url
      sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
             annotation:options[UIApplicationOpenURLOptionsAnnotationKey]];

  BOOL google = [RNGoogleSignin application:application openURL:url options:options];

  return facebook || google;
}

@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:**

info Fetching system and libraries information...
System:
    OS: macOS High Sierra 10.13.6
    CPU: (8) x64 Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
    Memory: 600.25 MB / 16.00 GB
    Shell: 5.3 - /bin/zsh
  Binaries:
    Node: 12.3.1 - /usr/local/bin/node
    Yarn: 1.16.0 - /usr/local/bin/yarn
    npm: 6.9.0 - /usr/local/bin/npm
    Watchman: 4.7.0 - /usr/local/bin/watchman
  SDKs:
    iOS SDK:
      Platforms: iOS 12.1, macOS 10.14, tvOS 12.1, watchOS 5.1
    Android SDK:
      API Levels: 17, 18, 21, 26
      Build Tools: 21.1.2, 26.0.3
      System Images: a...-18 | Intel x86 Atom, a...-tv | Android TV ARM EABI v7a System..., a... | Android TV Intel x86 Atom Syst..., a...ear | Android Wear ARM EABI v7a Syst..., a...ndroid-wear | Android Wear Intel x86 Atom Sy..., a...ult | ARM EABI v7a, a...-21 | Intel x86 Atom, a... | Intel x86 Atom_64, a...google_apis | Google APIs Intel x86 Atom Sys...
  IDEs:
    Xcode: 10.1/10B61 - /usr/bin/xcodebuild
  npmPackages:
    @react-native-community/cli: 2.9.0 => 2.9.0
    react: 16.9.0 => 16.9.0
    react-native: 0.61.2 => 0.61.2
  npmGlobalPackages:
    create-react-native-app: 1.0.0
    react-native-cli: 2.0.1
- **Platform that you're experiencing the issue on**: - [ ] iOS - [ ] Android - [x] **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:** - `6.0.2` - **`Firebase` module(s) you're using that has the issue:** - `functions` - **Are you using `TypeScript`?** - `Y` & `3.6.3`




Think react-native-firebase is great? Please consider supporting all of the project maintainers and contributors by donating via our Open Collective where all contributors can submit expenses. [Learn More]

Stale

Most helpful comment

I ran into this issue and I found many threads talking about regions. However, the issue for me was trying to call a "request" and not a "callable".

Try converting your cloud function from a request...

const processTransaction = functions.https.onRequest(async (req, res) => {
    // process some transaction
    res.sendStatus(200).send(responseData)
}

to a callable...

const processTransaction = functions.https.onCall(async (data, context) => {
    // process some transaction
    return responseData
}

All 11 comments

What does your helloWorld function return?

Hi, @gmertk! Is your function deployed to a specific region? If yes, you can try the solution in https://github.com/invertase/react-native-firebase/issues/2700.

@Ehesp, is it possible to include a sample of using function in a specific region in the getting started doc?

@Ehesp it returns an object as you can see in the sample code. Am I missing something?

Hi @arisferyanto I'm using the default region us-central1. I've also tried the following code, but still the same error.

      const region = 'us-central1';
      const fnName = 'helloWorld';
      const functions = firebase.app().functions(region);
      functions.useFunctionsEmulator('http://localhost:5001');
      const response = await functions.httpsCallable(fnName)();

Also I can see that the helloWorld function is called on the emulator logs:

➜  functions git:(master) ✗ firebase emulators:start
i  Starting emulators: ["functions"]
⚠  Your requested "node" version "8" doesn't match your global version "12"
✔  functions: Emulator started at http://localhost:5001
...
✔  functions[helloWorld]: http function initialized (http://localhost:5001/testProject/us-central1/helloWorld).
✔  All emulators started, it is now safe to connect.
i  functions: Beginning execution of "helloWorld"
i  functions: Finished "helloWorld" in ~1s
i  functions: Beginning execution of "helloWorld"
i  functions: Finished "helloWorld" in ~1s

Hello 👋, to help manage issues we automatically close stale issues.
This issue has been automatically marked as stale because it has not had activity for quite some time. Has this issue been fixed, or does it still require the community's attention?

This issue will be closed in 15 days if no further activity occurs.
Thank you for your contributions.

Closing this issue after a prolonged period of inactivity. If this is still present in the latest release, please feel free to create a new issue with up-to-date information.

@gmertk Did you figure this out?

Nope! Do you have the same issue?

I have the same case.

"dependencies": {
    "@react-native-community/masked-view": "^0.1.7",
    "@react-native-firebase/app": "^6.4.0",
    "@react-native-firebase/crashlytics": "^6.4.0",
    "@react-native-firebase/functions": "^6.4.0",
    "@react-native-firebase/remote-config": "^6.4.0",
    "@react-navigation/native": "^5.1.5",
    "@react-navigation/stack": "^5.2.10",
    "opentok-react-native": "^0.13.0",
    "react": "16.11.0",
    "react-native": "0.62.2",
    "react-native-gesture-handler": "^1.6.1",
    "react-native-i18n": "^2.0.15",
    "react-native-paper": "^3.8.0",
    "react-native-reanimated": "^1.8.0",
    "react-native-safe-area-context": "^0.7.3",
    "react-native-screens": "^2.4.0",
    "react-native-vector-icons": "^6.6.0",
    "react-redux": "^7.2.0",
    "redux": "^4.0.5",
    "redux-thunk": "^2.3.0"
  },

RN Code

import functions from '@react-native-firebase/functions';

export const createToken = () => {
  return dispatch => {
    functions()
      .httpsCallable('helloWorld')()
      .then(response => {
        console.log('HELLO WORLD');
      });
  };
};

@gmertk do you have any solution?

I don't exactly remember how I got this solved, but here is the code working fine right now.

import firebase from '@react-native-firebase/app';
import '@react-native-firebase/functions';

const defaultApp = firebase.app();
const functionsForRegion = defaultApp.functions('europe-west2');
if (__DEV__) {
  functionsForRegion.useFunctionsEmulator('http://localhost:5001');
}

export async function saveFCMToken(fcmToken: string): Promise<boolean> {
  try {
    const {data} = await functionsForRegion.httpsCallable('saveFCMToken')({
      fcmToken,
    });
    return data;
  } catch (e) {
    console.log(e);
    return false;
  }
}
        const saved = await saveFCMToken("some token here");

I run the emulator with firebase emulators:start --only functions.
firebase --version is 8.0.2.
react-native-firebase v6.4.0.

I ran into this issue and I found many threads talking about regions. However, the issue for me was trying to call a "request" and not a "callable".

Try converting your cloud function from a request...

const processTransaction = functions.https.onRequest(async (req, res) => {
    // process some transaction
    res.sendStatus(200).send(responseData)
}

to a callable...

const processTransaction = functions.https.onCall(async (data, context) => {
    // process some transaction
    return responseData
}
Was this page helpful?
0 / 5 - 0 ratings