'Flutter + firebase: Configure app to use local firebase emulator
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:
Solution 1:[1]
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.
Solution 2:[2]
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,
);
Solution 3:[3]
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());
}
Solution 4:[4]
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));
Solution 5:[5]
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
Solution 6:[6]
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;
}
Solution 7:[7]
Latest Update: To connect flutter app to your local firebase emulator suite, follow this official instruction for configuration.
Solution 8:[8]
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
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | UsmanZaheer |
| Solution 2 | S1ngoooor |
| Solution 3 | Samrat |
| Solution 4 | Shakle |
| Solution 5 | Mehmet Artun |
| Solution 6 | Alex.F |
| Solution 7 | sarru1291 |
| Solution 8 |

