Hey Invertase team 馃敟 馃敟 馃敟!
You are doing a great job (:
I'm facing some strange issue, I can't make the function app to use my local function emulator.
I followed all installation steps, everything is working except pointing the code to use my local machine, it runs directly on the cloud.
My app is IOS only, therefor android not tested.
My react code that uses Functions:
import firebase from "react-native-firebase";
firebase.functions().useFunctionsEmulator("http://localhost:5000");
export async function getCode() {
const getCodeFromBackend = firebase.functions().httpsCallable("getCode");
const result = await getCodeFromBackend();
return result.data.code;
}
Click To Expand
#### `ios/Podfile`: - [ ] I'm not using Pods - [x] I'm using Pods and my Podfile looks like:
platform :ios, '9.0'
target 'street' do
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
# use_frameworks!
# https://github.com/facebook/react-native/blob/v0.59.4/React.podspec
pod 'React', :path => '../node_modules/react-native', :subspecs => [
'Core',
'CxxBridge',
'DevSupport',
'RCTAnimation',
'RCTNetwork',
'RCTText',
'RCTWebSocket',
'RCTImage',
]
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 'FBSDKCoreKit', '~> 4.42.0'
pod 'FBSDKLoginKit', '~> 4.42.0'
pod 'FBSDKShareKit', '~> 4.42.0'
pod 'react-native-fbsdk', :path => '../node_modules/react-native-fbsdk'
pod 'Firebase/Core', '~> 5.20.1'
pod 'Firebase/Functions', '~> 5.20.1'
pod 'Firebase/Messaging', '~> 5.20.1'
pod 'Firebase/Auth', '~> 5.20.1'
pod 'RNFirebase', :path => '../node_modules/react-native-firebase/ios'
pod 'RNCAsyncStorage', :path => '../node_modules/@react-native-community/async-storage'
pod 'RNGestureHandler', :path => '../node_modules/react-native-gesture-handler'
pod 'RNLocalize', :path => '../node_modules/react-native-localize'
pod 'RNSVG', :path => '../node_modules/react-native-svg'
pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'
end
#### `AppDelegate.m`:
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <FBSDKCoreKit/FBSDKCoreKit.h>
#import <FBSDKLoginKit/FBSDKLoginKit.h>
#import <FBSDKShareKit/FBSDKShareKit.h>
#import <Firebase/Firebase.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[FIRApp configure];
[[FBSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
moduleName:@"kipp"
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
}
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
BOOL handled = [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]
];
// Add any custom logic here.
return handled;
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[FBSDKAppEvents activateApp];
}
@end
Click To Expand
#### `android/build.gradle`:
// N/A
#### `android/app/build.gradle`:
// N/A
#### `android/settings.gradle`:
// N/A
#### `MainApplication.java`:
// N/A
#### `AndroidManifest.xml`:
<!-- N/A -->
Click To Expand
**`react-native info` output:**
React Native Environment Info:
System:
OS: macOS 10.14.3
CPU: (8) x64 Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
Memory: 165.87 MB / 16.00 GB
Shell: 5.7.1 - /usr/local/bin/zsh
Binaries:
Node: 11.14.0 - ~/.nvm/versions/node/v11.14.0/bin/node
Yarn: 1.15.2 - ~/.yarn/bin/yarn
npm: 6.7.0 - ~/.nvm/versions/node/v11.14.0/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 12.2, macOS 10.14, tvOS 12.2, watchOS 5.2
IDEs:
Xcode: 10.2/10E125 - /usr/bin/xcodebuild
npmPackages:
react: 16.8.3 => 16.8.3
react-native: 0.59.8 => 0.59.8
- **Platform that you're experiencing the issue on**:
- [x] iOS
- [ ] Android
- [x] **iOS** but have not tested behavior on Android
- [ ] **Android** but have not tested behavior on iOS
- [ ] Both
- **`Firebase` module(s) you're using that has the issue:**
- `Functions`
- **Are you using `TypeScript`?**
- `N`
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]
React Native Firebase
and Invertase
on Twitter for updates on the library.Hey @moshe which version of RNFB are you using?
from package.json:
{"react-native-firebase": "^5.3.1"}
from package-lock.json:
{
"react-native-firebase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/react-native-firebase/-/react-native-firebase-5.3.1.tgz",
"integrity": "sha512-eOuSqIl+DZPNmN5ivSLgkEcsl5m0sXxttoPBn3bOHfI+apEd4I8F+9fcbHerUFUvLzesXmHR9locjhR6IJ+q3w==",
"requires": {
"opencollective-postinstall": "^2.0.0",
"prop-types": "^15.6.2"
}
}
It was a long night but we finally able to solve it.
Seems like calling [FIRFunctions functionsForApp:firebaseApp region:region]
in RNFirebaseFunctions.m creates a new instance of Cloud Functions client every time (docs) and losing the emulator context.
We added a small patch to RNFB locally
diff --git 1/node_modules/react-native-firebase/ios/RNFirebase/functions/RNFirebaseFunctions.m 2/scripts/files/RNFirebaseFunctions.m
index ef5eba7..2e73c22 100644
--- 1/node_modules/react-native-firebase/ios/RNFirebase/functions/RNFirebaseFunctions.m
+++ 2/scripts/files/RNFirebaseFunctions.m
@@ -7,6 +7,8 @@
#import <FirebaseFunctions/FIRError.h>
@implementation RNFirebaseFunctions
+FIRFunctions *functions;
+
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(httpsCallable:
@@ -22,8 +24,10 @@ RCT_EXPORT_METHOD(httpsCallable:
rejecter:
(RCTPromiseRejectBlock) reject
){
- FIRApp *firebaseApp = [RNFirebaseUtil getApp:appName];
- FIRFunctions *functions = [FIRFunctions functionsForApp:firebaseApp region:region];
+ if (functions == nil) {
+ FIRApp *firebaseApp = [RNFirebaseUtil getApp:appName];
+ functions = [FIRFunctions functionsForApp:firebaseApp region:region];
+ }
FIRHTTPSCallable *callable = [functions HTTPSCallableWithName:name];
@@ -64,8 +68,10 @@ RCT_EXPORT_METHOD(useFunctionsEmulator:
rejecter:
(RCTPromiseRejectBlock) reject
){
- FIRApp *firebaseApp = [RNFirebaseUtil getApp:appName];
- FIRFunctions *functions = [FIRFunctions functionsForApp:firebaseApp region:region];
+ if (functions == nil) {
+ FIRApp *firebaseApp = [RNFirebaseUtil getApp:appName];
+ functions = [FIRFunctions functionsForApp:firebaseApp region:region];
+ }
[functions useFunctionsEmulatorOrigin:origin];
resolve([NSNull null]);
}
It's probably not the right change as it not putting the region and the app into account.
Probably need to create a map of (region
, app
) -> functionsClient
but we not feeling comfortable as yesterday was the first time we declared a variable in Objective-C 馃榾
Or maybe it is something we missing?
Correct change or not, that's a huge +1 for being so resourceful and finding at least the apparent cause...
This is handled on v6 correctly;
We keep the specified origin in JS:
https://github.com/invertase/react-native-firebase/blob/master/packages/functions/lib/index.js#L82
and send it as an argument on every function request:
https://github.com/invertase/react-native-firebase/blob/master/packages/functions/ios/RNFBFunctions/RNFBFunctionsModule.m#L34
If you're looking to get this on v5, perhaps backporting the v6 changes would be the way to go here; keeping a singleton on native works but isn't a long term solution and will cause issues with app.delete() and potentially RN reloads.
This is only needed on iOS as the Android SDK already persists this.
I created a patchfile with patch-package and got this working w/ the iOS simulator. Thanks @moshe
diff --git a/node_modules/react-native-firebase/ios/RNFirebase/functions/RNFirebaseFunctions.m b/node_modules/react-native-firebase/ios/RNFirebase/functions/RNFirebaseFunctions.m
index ef5eba7..5e3ed35 100644
--- a/node_modules/react-native-firebase/ios/RNFirebase/functions/RNFirebaseFunctions.m
+++ b/node_modules/react-native-firebase/ios/RNFirebase/functions/RNFirebaseFunctions.m
@@ -7,6 +7,8 @@
#import <FirebaseFunctions/FIRError.h>
@implementation RNFirebaseFunctions
+FIRFunctions *functions;
+
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(httpsCallable:
@@ -22,8 +24,11 @@ @implementation RNFirebaseFunctions
rejecter:
(RCTPromiseRejectBlock) reject
){
- FIRApp *firebaseApp = [RNFirebaseUtil getApp:appName];
- FIRFunctions *functions = [FIRFunctions functionsForApp:firebaseApp region:region];
+ if (functions == nil) {
+ FIRApp *firebaseApp = [RNFirebaseUtil getApp:appName];
+ functions = [FIRFunctions functionsForApp:firebaseApp region:region];
+ }
+
FIRHTTPSCallable *callable = [functions HTTPSCallableWithName:name];
@@ -64,8 +69,10 @@ @implementation RNFirebaseFunctions
rejecter:
(RCTPromiseRejectBlock) reject
){
- FIRApp *firebaseApp = [RNFirebaseUtil getApp:appName];
- FIRFunctions *functions = [FIRFunctions functionsForApp:firebaseApp region:region];
+ if (functions == nil) {
+ FIRApp *firebaseApp = [RNFirebaseUtil getApp:appName];
+ functions = [FIRFunctions functionsForApp:firebaseApp region:region];
+ }
[functions useFunctionsEmulatorOrigin:origin];
resolve([NSNull null]);
}
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.
Most helpful comment
I created a patchfile with patch-package and got this working w/ the iOS simulator. Thanks @moshe