React-native-firebase: Using firestore emulator?

Created on 1 Dec 2019  ·  65Comments  ·  Source: invertase/react-native-firebase

Is there a way to point firestore to a local emulator in the same way as functions().useFunctionsEmulator('...') ?

Firestore Docs Question >= 6

Most helpful comment

Amazing, this really seem to work. :) Thank you @gruzinskis!

@Ehesp , thanks for further explanation. I've asked about async since I though we should be calling with await, but works ok without it.

@mikehardy , I think it would be a good idea to add that as a note to docs to save time on user and support side.

@sabinayakc , I think for now on android you should be using 10.0.2.2 instead of localhost. I store it in a firebase.js file from where I import different services (notice that this will load all services, so maybe in some cases you would want to load them separately - when they are actually needed):

import firebase from '@react-native-firebase/app'
import '@react-native-firebase/firestore'
import '@react-native-firebase/auth'
import '@react-native-firebase/messaging'
import '@react-native-firebase/functions'

// exports
export default firebase
export const db = firebase.firestore()
export const auth = firebase.auth()
export const messaging = firebase.messaging()
export const functions = firebase.functions()

//in DEV env use emulators
//TODO: https://github.com/invertase/react-native-firebase/pull/3690/files (only android redirects 10.0.2.2 to localhost)
if (__DEV__) {
  functions.useFunctionsEmulator('http://10.0.2.2:5001')
  db.settings({
    host: '10.0.2.2:8080',
  })
}

Thank you very much all!

All 65 comments

Unsure. What version you using (you didn't follow template, so no idea)?
What did you see when you checked the relevant doc site for the react-native-firebase version in use? Or the init code (it's trivial to trace through and can show you if there is room to pass in emulator config)

Here's the upstream docs to get a handle on it https://firebase.google.com/docs/emulator-suite/connect_and_prototype

Ah sorry, none of the templates were related to a question. I'm using 6.x

I have the emulators running locally. I originally tried looking for a function similar to useFunctionsEmulator in the react-native-firebase docs.

This is basically my setup:

import firestore from '@react-native-firebase/firestore'
const db = firestore()

Calling db.settings throws an error:

Exception 'FIRESTORE INTERNAL ASSERTION FAILED: Firestore instance has already been started and its settings can no longer be changed. you can only set settings before calling any other methods on a Firestore instance.'

Your link looks helpful, but I'm not sure where to put the swift code:

let settings = Firestore.firestore().settings
settings.host = "localhost:8080"
settings.isPersistenceEnabled = false 
settings.isSSLEnabled = false
Firestore.firestore().settings = settings

I appreciate your help. I'm new to react native, and I'm sure others will have this question in the future. Thanks.

The template is related to every problem, because it shows what versions are in use and how they are setup. Never ignore a template in a github repo. It also indicates what platform the problem is on. You don't indicate android or ios but if you mention swift, I'll try ios.

This module uses Objective-C not swift, so you'd want to use that version if you're hacking in the native code. But that shouldn't be necessary?

If you are on v6 then it appears the settings are available, have you tried them: https://invertase.io/oss/react-native-firebase/v6/firestore/reference/settings#host or is that what is throwing the error?

Appears to be wired up:
https://github.com/invertase/react-native-firebase/blob/master/packages/firestore/lib/index.js#L168
https://github.com/invertase/react-native-firebase/blob/master/packages/firestore/ios/RNFBFirestore/RNFBFirestoreModule.m#L88
https://github.com/invertase/react-native-firebase/blob/master/packages/firestore/ios/RNFBFirestore/RNFBFirestoreCommon.m#L74

Maybe you just need to do that setting prior to doing any other thing? Or maybe there is a startup configuration order-of-operations issue in the module where it "starts" firestore before you get control so you can't set it as things are now and the order of operations needs to change

The template is related to every problem, because it shows what versions are in use and how they are setup. Never ignore a template in a github repo.

There is not one template, but four. I don't see one for a question. "Documentation Feedback" seemed like the most relevant, since I was asking a question, so I clicked that one. But the template does not ask for that information. Just my feedback in case you want to improve it.

If you are on v6 then it appears the settings are available, have you tried them:

Right, that is what was throwing the error.

Here is my code:

import firestore from '@react-native-firebase/firestore'
firestore().settings({
  host: 'https://59f59951.ngrok.io',
  ssl: true,
})

(I'm using ngrok to avoid localhost).

I moved this code to the top of the main index.js entry file, which stopped the error from happening. However, now it's not hitting the network, and firestore is working offline instead. Rebuilding the app does not help.

If I remove the above code, the app uses production firestore and works fine.


On this page it states:

The default firebase app instance can not be initialized via JS. After following the iOS & Android installation guides and correctly setting up your google services plist/json files, the default app is automatically initialized and available for use in react-native-firebase.

which sounds like I shouldn't be trying to use firestore().settings() at all? This is why I originally asked my question.

Hmm - I should see about adding version information and platform and a link to the documentation under discussion in the template for documentation then, because if you were going to examine documentation feedback, how could you do it without pinning those things down? I'm not sure how, anyway

Interesting that you did see an effect moving it to top of index.js (even if that's pretty brutal) but a shame it did not fully work. Just to get moving I think for iOS you'd want to plop Objective-C config code right here https://github.com/invertase/react-native-firebase/blob/master/packages/firestore/ios/RNFBFirestore/RNFBFirestoreCommon.m#L33

@Salakar / @Ehesp this seems like maybe a candidate for firebase.json config mechanism, though that all seems to be static, or some delay on firestore setup such that a settings call first thing would be valid as indicated in underlying SDK https://firebase.google.com/docs/reference/android/com/google/firebase/firestore/FirebaseFirestore.html#setFirestoreSettings(com.google.firebase.firestore.FirebaseFirestoreSettings)

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.

Right, that is what was throwing the error.

Here is my code:

import firestore from '@react-native-firebase/firestore'
firestore().settings({
  host: 'https://59f59951.ngrok.io',
  ssl: true,
})

I believe you should be passing the host only, not the fully qualified url, so your host should be like the following (without https://):

import firestore from '@react-native-firebase/firestore'
firestore().settings({
  host: '59f59951.ngrok.io',
  ssl: true,
})

Also shouldn't there be a port, e.g. 59f59951.ngrok.io:8080? Not sure what ngrok is/does but the emulator on localhost starts with a port.

Side note: on Android Emulators you can use 10.0.2.2:8080 as the host to connect to localhost on your emulator host machine, if it's still not working with the above then I'd suggest trying the 10.0.2.2:8080 as the host with ssl: false - to confirm its not ngrok causing the issue.


I moved this code to the top of the main index.js entry file, which stopped the error from happening. However, now it's not hitting the network, and firestore is working offline instead. Rebuilding the app does not help.

If I remove the above code, the app uses production firestore and works fine.

This is the correct behaviour, settings needs to be called before any usage of Firestore in your app, so usually best at the top of your entry file.

Hi there, I'm facing (I believe) the same issue.

//index.js
import firestore from '@react-native-firebase/firestore'
firestore().settings({ host: 'http://localhost:8080', ssl: false })
firestore().collection('products').get().then(({ docs }) => console.log(docs))

I'm getting results from the remote firestore instead of the emulator. I have tried setting host to localhost:8080 (removing the protocol from it), but no success.

Am I missing something?

Update

Upon inspecting the emulator's log firestore-debug.log, I'm getting the following line appended every time I reload the app:

Dec 31, 2019 6:04:56 PM com.google.cloud.datastore.emulator.impl.util.WrappedStreamObserver onError
INFO: operation failed: null

It's just sad that the failure reason is null :/
The results are still coming from remote firestore though.

+1 here !

I think Firestore/Firebase - emulator is a big deal and it's really important to handle it.

Thanks a lots if someone find a way to do it or fix it !

I'm also having the same problem, using v6.2.0, I can't override firebase host with firebase.firestore().settings({ host: 'localhost:8080', ssl: false }).

This is actually all of my code for initializing firebase modules:

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

//TODO: why is this not working off of local host?
firebase.firestore().settings({
  host: 'localhost:8080',
  ssl: false,
});

// exports
export default firebase;
export const db = firestore();

I've used the debugger to track what's actually going on and settings() method of firebase module is called by the code that I've added and I was able to confirm with the debuger that correct settings are returned from line 225: https://github.com/invertase/react-native-firebase/blob/master/packages/firestore/lib/index.js#L225

Could it be that settings are just returned there without being applied?

Great information - thanks for posting that @tad3j - perhaps time to ping @Salakar again (sorry man :-) ) - there is something strange going on with the emulator, at least on iOS. I haven't tried firestore emulator but the functions emulator worked for me on Android but not iOS on device (not simulator) during investigation yesterday in #3114 - I was pretty careful to actually start the emulator listening on 0.0.0.0 and there was no firewall and the IP was right as near as I can tell. I was stumped.

Forgot to mention that I'm using Android... This works perfect on my WEB app, just having problems with mobile one (so according to that I would guess that problem is not in emulators).

For WEB app, my init looks like this:

import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';
import 'firebase/functions';
import config from '../../config/firebaseConfig';

firebase.initializeApp(config);

export default firebase;
export const db = firebase.firestore();

if (window.location.hostname === 'localhost') {
    firebase.functions().useFunctionsEmulator('http://localhost:5001');
    db.settings({
        host: "localhost:8080",
        ssl: false
    });
}

...and there I'm starting my emulator with node functions\node_modules\firebase-tools\lib\bin\firebase.js emulators:start --only firestore,functions

I got it working. The problem with my original code was the url – do not include the https:// part in your host string!

Also, if you're running on device, localhost is not going to work. Instead, you can use ngrok to forward multiple ports by first creating a ~/.ngrok2/ngrok.yml file like the this:

authtoken: xxx
tunnels:
  firestore:
    addr: 8080
    proto: http
    bind-tls: true
  functions:
    addr: 5001
    proto: http
    bind-tls: true

and then running ngrok start --all

🤦‍♂ so for the emulator, no protocol !?!, but obviously we want it in other cases? I'll try this again myself when I get a chance. Thanks a bunch for circling back

Yup. And, for the record, if you use the firebase functions emulator, you do put the protocol:

functions().useFunctionsEmulator('https://abc123.ngrok.io') // localhost:5001

Would be good to have some docs on these if anyone is willing to send a PR?

I still can't get RNF to connect to firestore running on localhost....it just ignores host setting and connect to live DB (code snippet posted above).

I've also tried to use FIRESTORE_EMULATOR_HOST env variable, but looks like this project is not using it (couldn't find mention on repo). Kind of running out of ideas what else to check.

Could anyone confirm this is a bug? Also, I guess this should work without changing native code or adding redirects?

I guess for writing documentation official firebase docs could be used (if implementation here will be the same):
https://firebase.google.com/docs/emulator-suite/connect_and_prototype#instrument_your_app_to_talk_to_the_emulators

for now I am ignoring it by only using the emulator when I test things on Android, making the bold assumption that if I get the functions right with that dev cycle then iOS is not going to change the result largely

for now I am ignoring it by only using the emulator when I test things on Android, making the bold assumption that if I get the functions right with that dev cycle then iOS is not going to change the result largely

I was referring to firestore DB emulator not functions one...does that work for you on Android? I haven't tried functions yet, but I would assume that it shouldn't be problematic (in my case all are called by firestore emulator on DB change).

Oh I'm sorry @tad3j - I haven't tested the DB emulator, only functions. For me, on android, the functions emulator is working, if that helps.

Would be better if we get both working. :)

I was debugging further today and I've noticed that firebase.app() returns an object who's databaseURL is the same as from my google-services.json file...so I can confirm that setting are not overridden (looks like something is off starting here native firebase module).

To test further I've tried to call firebase.initializeApp() to override settings, but RNF won't let me since it has been initialized by native module.

POTENTIAL ISSUE: I've then started looking into native code (unfortunately don't know how to debug that) where I came across a suspicious line in the code. The if statement checks for null equality with preferences, but the preferences variable is never set it seems...it's only initialized with private SharedPreferences preferences;. I guess that's why RNF uses configuration from file (assuming PREFERENCES_FILE is pointing to google-services.json) instead of overridden one. Could this be the cause of issue?

I think that line of code is causing the same issue for me when trying to override the 'persistence' setting in my app. I just can't turn it off, no matter what I try:

```
import firestore from '@react-native-firebase/firestore';
// TODO - doesn't seem to be disabling offline persistence
firestore().settings({ persistence: false })

@okcompewter does it work when you alter that line via an edit in node_modules?

I'm not sure how to go about editing it, honestly (I'm quite unfamiliar with java).

literally just go in to that file and hack at it, java syntax is not remarkably different than javascript. You can just convert

if (whateverTheThingIs == null) {

to

if (true) { // (whateverTheThingIs == null) {

... to hack out the logic check, then re run your android build - easy-peasy

I think to test out if the app's provided persistence settings are being thrown out for some default settings (what I believe @tad3j said is happening), I had to make this line false, but that gives an error in the app:

  private SharedPreferences getPreferences() {
    if (preferences == null && false) {
      preferences = ReactNativeFirebaseApp
        .getApplicationContext()
        .getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE);
    }
    return preferences;
  }

screenshot

If this is a bug, I'm not sure how to remove the default settings smashing any app settings while still providing valid app settings.

I've tested today if settings task inside UniversalFirebaseFirestoreModule.java gets executed by hardcoding localhost:8080 here (I've also tried to remove the if statement to force set it).

Even with that firebase.app() returns databaseURL from my file and not the hardcoded value. This makes me think that either .setStringValue() has no effect or that task is never executed and @ReactMethod settings is never called from js files.

Any idea why react wouldn't call native settings method?

In JS file I've tried with different order of this library inclusion, different import syntax, running settings before anything else, but nothing seems to solve the issue.

Haven't investigated a lot but another approach to testing with the emulators would be to use the apps from the @firebase/testing package through the initializeTestApp method which provides a firebase.app.App.

The problem is that there is type incompatibility between RNFirebase's FirebaseApp and firebase.app.App. So if I have an API that wraps an RNFirebase app and want to substitute it with a fireabse.app.App for testing, TypeScript complains. A workaround is to type it as any, but that means losing all the benefits of typing.

To clarify what I mean:

In my app I interact with Firestore through an API such as

interface API {
  doSomething(): Promise<void>
}
class FirebaseAPI implements API {
  constructor(private firestore) {}

  doSomething() {
    firestore.collection(...).[...doStuff]
  }
}

If I use RNFirebase to do that, firestore has the type provided by RNFirebase: FirebaseFirestoreTypes.Module. In my tests, I want to substitute this with test firestore objects provided by the @firebase/testing package, that allow interacting with the emulators. These have type firebase.firestore.Firestore, which have (correct me if I'm wrong) type incompatibilities with FirebaseFirestoreTypes.Module. The workaround would be

constructor(private firestore: any) {}

but the whole point of using types is then lost.

I've looked into the new documentation and realized that settings actually returns a promise (for the difference, official firebase-js-sdk return type is void), so one has to execute that async way (btw, documentation has a syntax problem here, function should be async).

So with that, I've added this code to my index.js file (firebase service where I want to configure it):

export const db = firebase.firestore()
;(async () => {
    try {
      await db.settings({
        host: '10.0.2.2:8080',
        ssl: false,
        // persistence: false, // disable offline persistence
      })
      console.log('databaseURL', db.app.options.databaseURL)
    } catch (e) {
      console.log('e', e)
    }
  })()

Still with that, databaseURL logged to console remains unchanged, so it seems like calling settings() has no effect (data is still loaded from live firestore instead of emulator). Should it work this way?

Was wondering, would there be any chance to remove async requirement for settings() method and keep the API sync with firebase-js-sdk API?

Hello, I've been trying to setup firestore + cloud function emulator locally to work with a react-native app with react-native-firebase and react-redux-firebase. The cloud functions worked out of the box when using useFunctionsEmulator setter. But with firestore, I had the same problems as you, until today accidentally I made it work.

Double checked multiple times - what happens is run firestore().settings({...), it never works, UNTIL you recompile and relaunch the app! (I ran react-native run-android, but I'm sure Android Studio run would also work). If I put the wrong firestore host in the settings, and refresh the react-native app - it still works with the emulated firestore instance. It starts using the address you set only after a recompile, either way, at this point I don't care why, because I was about to give up the 3rd time!

PS, I also noticed that the settings method returns a promise, but with the steps i just described, it also works without awaiting.

Was wondering, would there be any chance to remove async requirement for settings() method and keep the API sync with firebase-js-sdk API?

Unfortunately not, since we have to send the options to native, this needs to be async.

PS, I also noticed that the settings method returns a promise, but with the steps i just described, it also works without awaiting.

The promise will still be called, just you wont know when it completes.

it never works, UNTIL you recompile and relaunch the app!

So the way it works is by storing your settings in "local storage", and then when you use Firestore for the first time, it applies those settings. If you have already used Firebase, it will only work when the app is relaunched. This is because you can only set settings before usage, otherwise an error is thrown.

This is because you can only set settings before usage, otherwise an error is thrown.

Shouldn't the firestore().settings() throw the error then? It resolves to null for me.

Yeah it will always resolve - as mentioned above, it will use the settings when the next usage of a clean Firestore instance is created.

That one sounds like a really rough DX - maybe an info or warning message or at least docs indicating app restart is required for last-set settings to be in use

I have been unable to use the emulator for FireStore in v7.0. I tried setting the host to localhost 8080 in my index.js and also App.tsx of react-native. Any help would be highly appreciated.

@sabinayakc you might like the result of #3690

In React Native App, where should we initialize the emulator db.settings()? In other words which file?

Amazing, this really seem to work. :) Thank you @gruzinskis!

@Ehesp , thanks for further explanation. I've asked about async since I though we should be calling with await, but works ok without it.

@mikehardy , I think it would be a good idea to add that as a note to docs to save time on user and support side.

@sabinayakc , I think for now on android you should be using 10.0.2.2 instead of localhost. I store it in a firebase.js file from where I import different services (notice that this will load all services, so maybe in some cases you would want to load them separately - when they are actually needed):

import firebase from '@react-native-firebase/app'
import '@react-native-firebase/firestore'
import '@react-native-firebase/auth'
import '@react-native-firebase/messaging'
import '@react-native-firebase/functions'

// exports
export default firebase
export const db = firebase.firestore()
export const auth = firebase.auth()
export const messaging = firebase.messaging()
export const functions = firebase.functions()

//in DEV env use emulators
//TODO: https://github.com/invertase/react-native-firebase/pull/3690/files (only android redirects 10.0.2.2 to localhost)
if (__DEV__) {
  functions.useFunctionsEmulator('http://10.0.2.2:5001')
  db.settings({
    host: '10.0.2.2:8080',
  })
}

Thank you very much all!

@tadj3

I think for now on android you should be using 10.0.2.2

You can always do that, as the emulator uses that to access the host machine network. With #3690 though, you can also use localhost. Which means you could skip a platform check as the iOS emulator accesses the host machine with localhost.

@gruzinskis, I understand right (clever solution :) ), but seems like that PR was not released yet (only merged), that's why I left a TODO inside the code pointing to it. :) Thanks for heads up!

@mikehardy , I think it would be a good idea to add that as a note to docs to save time on user and support side.

There's a PR link at the top right of every docs page I think :-)

@mikehardy, right, will try to, once I understand it and get the wording right. :)

However, I think I'm still experiencing an issue that might be related to async settings for firestore...it seems like my first write to DB is timing out. Could it be that with my code async setting request didn't finish yet? If so, any suggestion how to get around?

@tad3j put the request in the .then() block of settings method, or keep a variable that you set to true in the then() method, so you can start doing the requests when the variable is finally set true

@gruzinskis , I hoped I'll be able to keep my firestore settings in the same fashion as I have it in my web project, but since it seems that's not and won't be the case, I guess the only way for me is to dispatch a new action to my redux store (something like 'initFirebase') and wait for it to complete before dispatching any firestore related actions.

I'm wondering though if there may be a better way...since this should be only used in debug builds, code to implement emulation seems to be a bit too verbose. If I understand correctly the issue is that firestore is initialized in native code, and JS code loads after that so we can't just set initial settings from JS, we needs to request the change in async fashion. I wonder if configuring that on gradle level would make more sense (for debug build only)...

@tad3j I am unable to hit the firestore. I tried your solution but it still doesn't work :/
My cloud functions are able to hit the emulator tho. Just not the firestore. I have created docs via UI in firestore emulator and am trying to retrieve it from React Native App.

@sabinayakc , make sure you re-compile and re-open your app as @gruzinskis mentions in this comment...JS code I posted above works for sure in "@react-native-firebase/firestore": "^7.1.2",.

@tad3j where you using typescript or javascript? Because in typescript they ask for other keys on the settings object.

I am using the latest version and I am unable to use firestore emulator. Following @tad3j example.

Just to complement my comment:
I keep receiving this error after i tried the solution, before were just happening on the ios simulator but was working fine on the real device, now both are not working

[Firebase/Firestore][I-FST000001] Could not reach Cloud Firestore backend. Connection failed 1 times. Most recent error: failed to connect to all addresses
This typically indicates that your device does not have a healthy Internet connection at the moment. The client will operate in offline mode until it is able to successfully connect to the backend.

@Matgsan , I use JavaScript.
That's strange, I never seen that. Is your firestore emulator running on port 8080? Also make sure you re-compile and clear app data after you've changed the setting.

@Matgsan If you are running on a physical device with a usb cable (not bundler through network) then any localhost's used for connection need to be reverse proxied with adb reverse tcp:8080 tcp:8080 Or whatever port you want to read. If running the android emulator, use 10.0.2.2 to reach local workstation

I have tried putting 10.0.2.2:8080 for the android emulator

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

firestore().settings({
  host: '10.0.0.2:8080',
});

<RoundedButton
              text={t('begin')}
              textColor={GlobalStyle.colors.primary}
              handleOnPress={async () => {
                // setIsLoading(true);

                console.log('set');
               const res = await firestore()
                  .collection('users')
                  .doc('epvPnwg9o72pOv4828oGu')
                  .get();

                console.log(res.data());
              }}
            />

And I get the following error:

Error: [firestore/unknown] An unknown error occurred
NativeFirebaseError: [firestore/unknown] An unknown error occurred

If I try to add an item firestore().collection('users').doc('epvPnwg9o72pOv4828oGu').set(); it just blocks and does nothing...

Can someone help it does'nt seem to connect to the emulator?

Try setting the ssl flag to false?

Thanks for your help. No it does the same thing...

Ok I made it work by doing the following:

firebase emulators:start
adb uninstall "[PROJECT]" (important)
react-native start
react-native run-android
firestore().settings({ persistence: false, host: '10.0.2.2:8080', ssl: false, });

Works on the android emulator

I'm trying with android device but it does not work for me.

I did the same as above, tried with ngrok

firestore().settings({ persistence: false, host: '6ad3074a9b12.ngrok.io', ssl: false, });

But I have:

Error: [firestore/unknown] An unknown error occurred NativeFirebaseError: [firestore/unknown] An unknown error occurred

Any suggestions?

Ok if it might interest, my workaround, by using the firestore emulator to the android device by usb cable, was by doing as followed:

firebase.json
```{
...
"emulators": {
"firestore": {
"port": 8080,
"host": "192.168.0.*" (this should be the ip address of your local machine, or you could simply enter: 0.0.0.0)
}
}
}


Then I did: 

firestore().settings({
persistence: false,
// same ip as in firebase.json
host: '192.168.0.*:8080',
ssl: false,
});
```

I then did'nt have to do adb reverse ... or use ngrok

Hope it might help

src: https://stackoverflow.com/questions/58260877/access-firebase-emulator-from-local-network

Hello, I've been trying to setup firestore + cloud function emulator locally to work with a react-native app with react-native-firebase and react-redux-firebase. The cloud functions worked out of the box when using useFunctionsEmulator setter. But with firestore, I had the same problems as you, until today accidentally I made it work.

Double checked multiple times - what happens is run firestore().settings({...), it never works, UNTIL you recompile and relaunch the app! (I ran react-native run-android, but I'm sure Android Studio run would also work). If I put the wrong firestore host in the settings, and refresh the react-native app - it still works with the emulated firestore instance. It starts using the address you set only after a recompile, either way, at this point I don't care why, because I was about to give up the 3rd time!

PS, I also noticed that the settings method returns a promise, but with the steps i just described, it also works without awaiting.

@gruzinskis I followed this but, my app crashes after adding a document.

I using the latest react-native-firebase and I am also using react-redux-firebase. When I remove the setting(reset it to default), all my sample documents are saved into the production database (Firestore).

Hi
I am also unable to connect my android app to the local emulator.

Minimal index.js I used to reproduce this:

/**
 * @format
 */

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

import {name as appName} from './app.json';

const db = firestore();
db.settings({host: 'localhost:8080'}).then(() => {
    console.log('done setting');
});

AppRegistry.registerComponent(appName, () => {
    return function App(){
        return (
            <View style={{flex:1, backgroundColor:'#aaa'}}>
                <Button onPress={async() => {
                    console.log(db.app.options.databaseURL);
                    const doc = await db.collection('users').doc('some_id').get()
                    console.log(doc.data());
                }} title='Hello' />
            </View>
        )
    }
});

My device is connected through usb cable. I started firebase emulator, ran adb reverse tcp:8080 tcp:8080, uninstalled the app, then ran react-native run-android.

The databaseURL is always https://{projectid}.firebaseio.com,

I noticed this in adb logcat when I first pressed the button:

Firestore: (21.4.3) [OnlineStateTracker]: Could not reach Cloud Firestore backend. Connection failed 1 times. Most recent error: Status{code=UNAVAILABLE, description=null, cause=javax.net.ssl.SSLHandshakeException: Handshake failed

I use:
react-native: 0.62.2
react: 16.11.0
@react-native-firebase/app: 7.1.0
@react-native-firebase/firestore: 7.1.0
@react-native-firebase/storage: 7.1.0
@react-native-firebase/messaging: 7.1.0

@mikehardy

Somebody please..!

My device is connected through usb cable.

Try using the IP of your computer instead of localhost?

Try using the IP of your computer instead of localhost?

To connect using the IP address the device and the computer should be connected to the same network right?
I tried using IP address in both ways. It failed with errors host unreachable when not connected in the same network and ECONNREFUSED when in the same network.

Then I tried the IP 0.0.0.0 as host address of the emulator instead of localhost. Now when both are connected in the same network, it shows the same old error(javax.net.ssl.SSLHandshakeException: Handshake failed).

Anyways, thanks for replying!

Honestly it depends on your network setup - usually localhost works but sometimes it may need an IP which is forwarded. Also, make sure ssl is false when using a local host.

I connected the device and the computer to the same network, used db.settings({ssl: false, host: '192.168.*.*:8080'}) and set firestore host to 0.0.0.0 in firebase.json. Now it is working! Thank you!

Closing as working example has been found.

Please re-open if this does not solve the issue.

Was this page helpful?
0 / 5 - 0 ratings