Flutter + firebase: Configure app to use local firebase emulator

Issue

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

Solution

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();
  }
}

Answered By – sultanmyrza

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published