invertase / react-native-firebase

๐Ÿ”ฅ A well-tested feature-rich modular Firebase implementation for React Native. Supports both iOS & Android platforms for all Firebase services.
https://rnfirebase.io
Other
11.7k stars 2.22k forks source link

[๐Ÿ›] ๐Ÿ”ฅ Cannot connect to Firestore emulator (but I can connect to Auth emulator) #5589

Closed jacobmolby closed 2 years ago

jacobmolby commented 3 years ago

Issue

Hello I cannot get my RN app to connect to the Firestore Emulator. It works for the Auth Emulator and it correctly prints the confirmation code in emulator terminal, when using signInWithPhoneNumber().

import auth from '@react-native-firebase/auth';
auth().useEmulator('http://localhost:9099'); // this works :)

I've only tried it on iOS (simulator), but I don't get any errors. It simply uses the cache on the phone to perform the read/write ops.

import firestore from '@react-native-firebase/firestore';
const db = firestore();
db.settings({
      host: 'localhost:8080',
      ssl: false,
    })
// I've also tried with persistence: true and persistence: false, it doesn't make a difference.

When looking under "requests" in the emulator UI, I can see no requests are performed.

The cloud functions (also running in emulator) can connect and make changes to the Firestore without problems, when I call the endpoints from within my app.

I've tried to update to the latest version of RN-firebase (v.12.4.0 of all packages). Unfortunately it didn't make a difference.

I'm using Hermes as the JS engine.

Full example

import '@react-native-firebase/app';
import firestore from '@react-native-firebase/firestore';
import React, { useEffect, useState } from 'react';
import { AppRegistry, View, Button, Text } from 'react-native';
const db = firestore();

AppRegistry.registerComponent(appName, () => Tester);

const Tester = () => {
  const add = () => {
    db.collection('my-test-collection')
      .add({
        test: true,
      })
      .then(data => {
        console.log('item added', data.id);
      });
  };
  const [loading, setLoading] = useState(true);
  const [state, setState] = useState([]);
  const fetch = () => {
    db.collection('my-test-collection')
      .get()
      .then(data => {
        setState(data.docs.map(doc => doc.data()));
      });
  };

  useEffect(() => {
    db.settings({
      host: 'localhost:8080',
      ssl: false,
    }).then(() => {
      setLoading(false);
    });
  }, []);

  if (loading) return null;
  return (
    <View
      contentContainerstyle={{
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
      }}>
      <Button title="add" onPress={() => add()} />
      <Button title="fetch" onPress={() => fetch()} />
      <Text>{JSON.stringify(state, null, 2)}</Text>
    </View>
  );
};

The example is fully functional, but no writes are going to the emulator. Everything stays on device.

Please let me know if you need other information, than I've provided.

All the services are running


Project Files

Javascript

Click To Expand

#### `package.json`: ```json { "@react-native-firebase/analytics": "12.4.0", "@react-native-firebase/app": "12.4.0", "@react-native-firebase/auth": "12.4.0", "@react-native-firebase/crashlytics": "12.4.0", "@react-native-firebase/dynamic-links": "12.4.0", "@react-native-firebase/firestore": "12.4.0", "@react-native-firebase/functions": "12.4.0", "@react-native-firebase/messaging": "12.4.0", "@react-native-firebase/remote-config": "12.4.0", "@react-native-firebase/storage": "12.4.0", "react-native": "0.64.1", "react": "17.0.1", } ``` #### `firebase.json` for react-native-firebase v6: ```json { "react-native": { "crashlytics_debug_enabled": true, "analytics_auto_collection_enabled": true } } ```

iOS

Click To Expand

#### `ios/Podfile`: - [ ] I'm not using Pods - [x] I'm using Pods and my Podfile looks like: ```ruby # N/A ``` #### `AppDelegate.m`: ```objc // N/A ```


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`: ```groovy // N/A ``` #### `android/app/build.gradle`: ```groovy // N/A ``` #### `android/settings.gradle`: ```groovy // N/A ``` #### `MainApplication.java`: ```java // N/A ``` #### `AndroidManifest.xml`: ```xml ```


Environment

Click To Expand

**`react-native info` output:** ``` System: OS: macOS 11.5 CPU: (8) x64 Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz Memory: 869.20 MB / 16.00 GB Shell: 3.1.2 - /usr/local/bin/fish Binaries: Node: 16.4.0 - ~/.nvm/versions/node/v16.4.0/bin/node Yarn: 1.22.10 - /usr/local/bin/yarn npm: 7.18.1 - ~/.nvm/versions/node/v16.4.0/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.5, DriverKit 20.4, macOS 11.3, tvOS 14.5, watchOS 7.4 Android SDK: API Levels: 28, 29, 30 Build Tools: 28.0.3, 29.0.2, 29.0.3, 30.0.2 System Images: android-30 | Google APIs Intel x86 Atom Android NDK: Not Found IDEs: Android Studio: 4.0 AI-193.6911.18.40.6626763 Xcode: 12.5.1/12E507 - /usr/bin/xcodebuild Languages: Java: 1.8.0_242-release - /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/javac Python: 2.7.16 - /usr/bin/python npmPackages: @react-native-community/cli: Not Found react: 17.0.1 => 17.0.1 react-native: 0.64.1 => 0.64.1 react-native-macos: Not Found npmGlobalPackages: *react-native*: Not Found ``` - **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:** - `12.4.0` - **`Firebase` module(s) you're using that has the issue:** - `e.g. Instance ID` - **Are you using `TypeScript`?** - `Y` & `4.1.3`


mikehardy commented 3 years ago

I don't see anything immediately obvious :thinking: Things look right / generally match how we do things in /test/app.js here to connect

Could it be that firestore thinks you are offline for some reason?

Curious if the same experience persists on android emulator

snehsagarajput commented 3 years ago

@jacobmolby Can you try and test again with some other port number for firestore emulator?

mikehardy commented 3 years ago

I was actually just in this area (#5613) and improved the firestore emulator ergonomics. It used to be that you had to use the settings object and configure host + port + ssl==false - now you may just use firestore.useEmulator(host, port) - maybe give that a try with the current stable version here.

jacobmolby commented 3 years ago

Thanks for all the answers, and sorry for me not answering (I was on vacation last week).

I've updated the packages to v12.7.2 (and removed ios/build and reinstalled pods).

Unfortunately it still doesn't work for me, however the problem has changed: Now it just ignores the call and my requests are made up against the real database (instead of before where it seemed to just cache everything).

The useEmulator() function is called successfully as it returns the array: ['localhost', 8080].

The updated example code:

import '@react-native-firebase/app';
import firestore from '@react-native-firebase/firestore';
import React, { useEffect, useState } from 'react';
import { AppRegistry, View, Button, Text } from 'react-native';
import SplashScreen from 'react-native-splash-screen';

const db = firestore();
db.useEmulator('localhost', 8080);

AppRegistry.registerComponent("appName", () => Tester);

const Tester = () => {
  const add = () => {
    db.collection('my-test-collection')
      .add({
        test: true,
      })
      .then(data => {
        console.log('item added', data.id);
      });
  };
  const [state, setState] = useState([]);
  const fetch = () => {
    db.collection('my-test-collection')
      .get()
      .then(data => {
        setState(data.docs.map(doc => doc.data()));
      });
  };

  useEffect(() => {
    SplashScreen.hide();
  }, []);

  return (
    <View
      style={{
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center',
      }}>
      <Button title="add" onPress={() => add()} />
      <Button title="fetch" onPress={() => fetch()} />
      <Text>{JSON.stringify(state, null, 2)}</Text>
    </View>
  );
};

Could be something with my environment that is wrong, since it seems like the this.native.useEmulator(_host, port) is simply ignored?

mikehardy commented 3 years ago

This may or may not work but under no circumstances use that splash screen library https://github.com/crazycodeboy/react-native-splash-screen/issues/289#issuecomment-502406454

It hasn't been updated in more than a year. You want https://github.com/zoontek/react-native-bootsplash

Either way, as long as it's in there the example is still not minimal, strip it down to the smallest example you can - this stuff is definitely supposed to work, I was obviously just in there adding the useEmulator function and I tested it - I know it hits the emulator when used correctly :thinking:

jacobmolby commented 3 years ago

Okay, thank you we'll definitely change the library.

findmory commented 2 years ago

@jacobmolby this exact same thing happened to me and the reason was that my firestore.rules had a rule that wasn't allowing the DB transactions. For example if you start out in dev mode and your rule is date based like this:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if
          request.time < timestamp.date(2021, 12, 18);
    }
  }
}

Then after Dec-18, 2021 your DB connections will fail. TBH they will fail pretty silently, but you can see the failed requests in the emulator if you go to Firestore and then the Requests tab Screen Shot 2022-01-22 at 1 44 53 PM

ftaibi commented 1 month ago

Did you fix it? I am having the same issue When I use firestore().useEmulator(host, port) I dont see the data in the db in the emulator UI but I also dont get any error when writing, seems like the data is just cashed but not sent to firestore db

zchryst commented 2 weeks ago

I've just run into a similar problem ie. auth emulator works but connecting to the firestore emulator doesn't. I solved it by allowing HTTP requests to localhost in my info.plist. I hope that helps someone.

More info about how to do that here https://revs.runtime-revolution.com/connecting-react-native-to-localhost-65e7ddf43d02