23

I have configured firebase to run locally for debugging using the emulator by following this link.

Now I want to be able to run my app connected to the localhost for debugging triggers as well. Is there a way to achieve this by configuring my flutter app to use the localhost?

My emulator is running as following:

enter image description here

2
  • 6
    Please don't show images of text. It's better to copy the text directly into the question so it's easier to read and search. Commented Nov 4, 2019 at 12:52
  • If you only need to partially configure your app. For example, only firestore or only functions. You can use the code here: tianhaoz.com/eng/server/firebase/… Commented Apr 18, 2020 at 19:36

10 Answers 10

48

My latest setup of flutter fire

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  
  await Firebase.initializeApp();

  const bool USE_EMULATOR = true;

  if (USE_EMULATOR) {
    // [Firestore | localhost:8080]
    FirebaseFirestore.instance.settings = const Settings(
      host: 'localhost:8080',
      sslEnabled: false,
      persistenceEnabled: false,
    );
    
    // [Authentication | localhost:9099]
    await FirebaseAuth.instance.useEmulator('http://localhost:9099');

    // [Storage | localhost:9199]
    await FirebaseStorage.instance.useEmulator(
      host: 'localhost',
      port: 9199,
    );
  }
}

Make sure your host and port matches from firebase emulators:start Make sure your host and port matches

NOTE: in main.dart now you can always provide 'localhost'

await FirebaseAuth.instance.useEmulator('http://localhost:9099');

because it will change automagically to '10.0.2.2' if it is running on android enter image description here

Long story short!

for latest guide follow https://firebase.flutter.dev/docs/firestore/usage#emulator-usage

Old but, Gold. Detailed config.(Outdated)

STEP 1 [setup firestore in flutter in main.dart]

Future<void> main() async {
  
    WidgetsFlutterBinding.ensureInitialized(); <--- Important!
      
    await Firestore.instance.settings(
            host: '192.168.1.38:5002', <--- Make sure to put your local ip 
            sslEnabled: false);             it will not work if you use 'localhost:5002'
                                            Google it "how to find my local ip"
       
}

STEP 1 [setup firestore in flutter in main.dart] for newer version of firebase

Future<void> main() async {
  
    WidgetsFlutterBinding.ensureInitialized(); <--- Important!
   
    String host = Platform.isAndroid ? '10.0.2.2:5002' : 'localhost:5002';
    await FirebaseFirestore.instance.settings = Settings(
         host: host,
         sslEnabled: false,
    );  
       
}

STEP 2 [init firebase project]

firebase init

STEP 3 [config firestore emulator e.g firebase.json]

"emulators": {
    "ui": {
      "enabled": true,
      "host": "localhost",
      "port": 4000
    },
    "functions": {
      "port": 5001
    },
    "firestore": {
      "host": "0.0.0.0", <------ Make sure to set it "0.0.0.0"
      "port": 5002
    },
}

STEP 4 [run emulators and flutter app]

firebase emulators:start
flutter run

Worked both on iOS simulator and Android emulators

P.S: try to restart firestore emulator or/and flutter app

Done!

BONUS [import export data to firestore emulator]

when you stop firestore emulator all data in firestore will be gone. So maybe before stoping emulator if you want to continue from where you left of you can export firestore emulator data like so

firebase emulators:export ../data (../data can be any path you want 😎)

to load exported data

firebase emulators:start --import ../data

you can save different states of your firestore emulator for different cases, example

firebase emulators:start --import ../initialData 
firebase emulators:start --import ../otherStateData

❤️ Note for myself use dart for firebase functions ❤️

If you want to use dart for firebase functions you can follow this https://github.com/pulyaevskiy/firebase-functions-interop

one good thing I found for myself to detect if your function is running in emulator or production you can read more here

long story short

functions/index.js

export const prepopulateFirestoreEmulator = functions.https.onRequest(
  (request, response) => {
    if (process.env.FUNCTIONS_EMULATOR && process.env.FIRESTORE_EMULATOR_HOST) {
      // TODO: prepopulate firestore emulator from 'yourproject/src/sample_data.json
      response.send('Prepopulated firestore with sample_data.json!');
    } else {
      response.send(
        "Do not populate production firestore with sample_data.json"
      );
    }
  }
);

functions/index.dart

import 'package:firebase_functions_interop/firebase_functions_interop.dart';
import 'package:node_interop/node.dart';
import 'package:node_interop/util.dart';

void devPrepopulateCollections(ExpressHttpRequest request) {
  var env =
      new Map<String, String>.from(dartify(process.env)); // <-- important part

  if (env.containsKey('FUNCTIONS_EMULATOR') &&
      env.containsKey('FIRESTORE_EMULATOR_HOST')) {
    // TODO: prepopulate firestore emulator from 'yourproject/src/sample_data.json
    request.response
      ..write("Prepopulated firestore with sample_data.json!")
      ..close();
  } else {
    request.response
      ..write("Do not populate production firestore with sample_data.json")
      ..close();
  }
}
Sign up to request clarification or add additional context in comments.

14 Comments

Thanks for these instructions! This even worked with my connected Android device.
now flutter have official instructions on setting up firebase emulator for flutter firebase.flutter.dev/docs/firestore/usage#emulator-usage
Could you update this for how to connect to Realtime Database emulator? I can't figure out the magic incantation needed...
the official instructions work for using Android or iOS simulators. But for testing in physical devices, needs Firestore host "0.0.0.0" + local IP combination
@SultanmyrzaKasymbekov thanks for answer! Do you know same solution for using Firebase Emulator with FirebaseAuth and Flutter?
|
3

After carefully going through the docs here, I got it working by configuring the host setting on the firestore instance:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:tracker/screens/screens.dart';

void main() async {

  // This will set the app to communicate with localhost
  await Firestore.instance.settings(host: "10.0.2.2:8080", sslEnabled: false);

  runApp(AppSetupScreen());
}

Note: This will only work with emulator and not with physical device.

3 Comments

does it work in iOS simulator? Ive tried using it and requests still go to the firebase not firebase emulator :/
I haven't tried it in iOS simulator sorry :/, but it should work by giving "localhost:8080" as the host as specified in docs.
@kashlo Yes it works for both iOS/Android if you follow this stackoverflow.com/a/62586957/6133329
3

An add-on:

To make the Firebase emulators work with the physical devices

Work for both iOS and Android devices

1. Cloud functions setup:

in firebase.json

{
  // ...other configs
  "emulators": {
    "functions": {
      "port": 5001,
      "host": "0.0.0.0" // must have
    },
    "firestore": {
      "port": 8080,
      "host": "0.0.0.0" // must have
    },
  }
}

2. Your Flutter app setup:

The IP address you use for cloud functions and firestore should be the same

// The FirebaseFunctions config
// ! You need to replace the placeholder with your IP address below:
FirebaseFunctions.instance.useFunctionsEmulator(origin: 'http://<YOUR_IP_ADDRESS>:5001');

// The Firestore config
// ! You need to replace the placeholder with your IP address below:
FirebaseFirestore.instance.settings = Settings(
  host: '<YOUR_IP_ADDRESS>:8080',
  sslEnabled: false,
  persistenceEnabled: false,
);

Comments

1

for cloud_firestore: ^0.14.1+2, instead of using FirebaseFirestore.instance.settings use this -

FirebaseFunctions.instance.useFunctionsEmulator(
    origin: "http://localhost:5001",
  );

It internally handles setting up 10.0.2.2 if the device is android.

Your main block should look like the following

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  FirebaseFunctions.instance.useFunctionsEmulator(
    origin: "http://localhost:5001",
  );
  runApp(MyApp());
}

1 Comment

I think you're mixing functions and firestore.
1

My init function looks like so:

init_firebase.dart

Future<void> initFirebase() async {
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  if (!kReleaseMode) {
    try {
      await Future.wait([
        FirebaseAuth.instance.useAuthEmulator('localhost', 9099),
        FirebaseStorage.instance.useStorageEmulator('localhost', 9199),
      ]);

      FirebaseFunctions.instance.useFunctionsEmulator('localhost', 5001);
      FirebaseFirestore.instance.useFirestoreEmulator('localhost', 8080);
    } catch (e) {}
  }
}

By using !kReleaseMode, we don't have to have a boolean that we switch each time. It will just use emulator by default during development

By wrapping it in try-catch block we avoid some errors from hot reload

2 Comments

Thank you for this. But what if I am running the debug app on a physical device, won't this run into a problem? Since, though it's not in release mode, it's also not in emulator?
You are correct, I at one point used stackoverflow.com/questions/49866014/… to auto determine if it was a physical device. Now though I just keep it simple and use a simple file with some dev flags including const bool devSimulate = kDebugMode && false; I just change it from false to true if I want to use the emulator. The kDebugMode is there just a fallback incase I forget to change it back before production.
0

Looks like i've connected ios to localhost:8080, but db works very slow and I also didn't notice any logs in a file. @UsmanZaheer, can you please tell when did it write logs and was it working fast?

Steps:

  • firebase init

  • add links that have been created by ini to package.json in functions;

    "firestore": { "rules": "firestore.rules", "indexes": "firestore.indexes.json" },

  • firebase emulators:start

in main() write

await Firestore.instance.settings(
      host: 'http://localhost:8080',
      sslEnabled: false,
      persistenceEnabled: false,
      timestampsInSnapshotsEnabled: true
  ).catchError((e) => print(e));

1 Comment

The emulator is just for debugging purposes, I used it to debug my cloud functions. When you create an auth user it is saved to firestore as there is no auth emulator currently, as for other data, I can't really say where it stores the data (maybe in memory). The emulator just shows in console that the function was hit and success or errors.
0

Adjustment for Flutter Web

addition to the correct answer by @Sultanmyrza

Platform requires dart:io/dart:html which are mutually exclussive so to check for the platform I use kIsWeb

FirebaseFirestore __firestore;
FirebaseFirestore get _firestore {
  if (__firestore != null) {
    return __firestore;
  }
  debugPrint('isFirebaseEmulator: $isFirebaseEmulator');
  __firestore = FirebaseFirestore.instance;
  if (isFirebaseEmulator) {
    __firestore.settings = const Settings(
      host: kIsWeb ? 'localhost:8080' : '10.0.2.2:8080',
      sslEnabled: false,
    );
  }
  return __firestore;
}

Comments

0

Latest Update: To connect flutter app to your local firebase emulator suite, follow this official instruction for configuration.

Comments

0

None of the above suggestions work with real device connecting to firebase emulator. the app connect with the real device and allows one to log in (even via sms - the emulator sends the code to its console without issue, but all over a sudden:

SocketException (SocketException: Connection refused (OS Error: Connection refused, errno = 111), address = localhost, port = 44224)

there is no where I have localost. On web it works perfectly, on firebase json, I have the broadcast IP 0.0.0.0, and on main, the IP address of the laptop, I have allowed ports for the firewall (in fact allowed all to avoid reasoning as a firewall issue), am connecting to the phone wireless network, so am on ip: 192.168.43.1, the same gateway for the laptop. the laptop is on 192.168.43.81.

So, not sure why the connection points to the localhost, and does not connect as long as the images are to be displayed...

any update on how to configure firebase emulators to connect to real device as latest as June 2023?

Comments

-1

Your main.dart should look like this:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firestore.instance
    .settings(
       host: 'http://localhost:8080',
       sslEnabled: false,
       persistenceEnabled: false,
     )
    .catchError((e) => print(e));
  // 
  // ...
  //
  runApp(App(...));
}

in your firebase.json file

  "emulators": {
    "firestore": {
          "host": "localhost",
          "port": 8080
    },
    ...
  }

you should also set the following in your terminal:

export FIRESTORE_EMULATOR_HOST=localhost:8080

and then run

firebase emulators:start

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.