Setting
I am developing on a test Firestore instance hosted on firebase, and I would like to run firebase emulators:start targeting this database. Currently it's targeting an emulator suite accessible through localhost:4000. In the codebase, I have initialized firebase instance with parameters for the actual instance as follows:
const fireAdmin = admin.initializeApp({
credential : admin.credential.applicationDefault()
, databaseURL : DatabaseConfig['databaseURL']
, storageBucket: DatabaseConfig['storageBucket']
});
where DatabaseConfig = { databaseURL: "https://mytestingserversite.firebaseio.com", ... }.
Problem
However, the functions are still writing/reading from the emulator instance. This is my firebase.json:
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"hosting": {
"rewrites": [
{
"source": "**",
"function": "app"
}
]
},
"functions": {
"source": "functions"
},
"emulators": {
"functions": {
"port": 5001
},
"firestore": {
"port": 8080
},
"hosting": {
"port": 5000
},
"ui": {
"enabled": true
}
}
}
Am I missing some env variable here?
The databaseURL parameter isn't really doing something here, as it is for specifying the Realtime Database URL.
Regardless of which emulator you are actually using, you can omit the Firestore emulator by just running the emulators you want.
For instance: firebase emulators:run --only functions,hosting
That should tell the CLI to use the actual Firestore instance in the Cloud and not the emulator.
Related
I'm currently trying to setup a locally environment with react native expo and React Native Firebase (using EAS to build). I've successfully connected the app with the authentication emulator receiving a verification code through phone authentication. However, I am not able to connect to the firestore emulator. The error I get when I try to fetch documents is the following
[Error: [firestore/unavailable] The service is currently unavailable. This is a most likely a transient condition and may be corrected by retrying with a backoff.]
I hope some of you guys can help me with a solution. Currently my code looks like this in index.js:
//index.js file
import Constants from "expo-constants";
import "#react-native-firebase/app";
import firestore from "#react-native-firebase/firestore";
import auth from "#react-native-firebase/auth";
if (__DEV__) {
const origin =
Constants.manifest?.debuggerHost?.split(":").shift() || "localhost";
firestore().useEmulator(origin, 8080);
auth().useEmulator("http://localhost:9099");
}
...
My firebase.json file looks like this:
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"storage": {
"rules": "storage.rules"
},
"functions": [
{
"source": "functions",
"codebase": "default",
"ignore": [
"node_modules",
".git",
"firebase-debug.log",
"firebase-debug.*.log"
],
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
]
}
],
"emulators": {
"auth": {
"port": 9099
},
"functions": {
"port": 5001
},
"firestore": {
"port": 8080
},
"pubsub": {
"port": 8085
},
"storage": {
"port": 9199
},
"ui": {
"enabled": true
},
"singleProjectMode": true
}
}
The issue:
I have a web project hosted on Firebase that deploys fine. I want to add a new site to the same project. Firebase fails to deploy went target is set.
Step to reproduce
Update Firebase CLI to 9.16.0
Create new site on Firebase hosting console. Name: autoscrib-testv2
Run firebase target:apply hosting test autoscrib-testv2
.firebaserc gets updated to:
{
"projects": {
"default": "autoscrib"
},
"targets": {
"autoscrib": {
"hosting": {
"test": [
"autoscrib-testv2"
]
}
}
}
}
Update firebase.json to
{
"database": {
"rules": "database.rules.json"
},
"hosting": {
"target":"test",
"public": "dist",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**"],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
],
"headers": [
{
"source": "/sw.js",
"headers": [
{
"key": "Cache-Control",
"value": "no-cache"
}
]
}
]
},
"storage": {
"rules": "storage.rules"
}
}
** Deploy Emulator works fine **
Run firebase emulators:start --only hosting:test
website deploys on localhost:5000
Error Message
Run firebase deploy --only hosting:test
Process stops while uploading files and show:
Task 38b07412931a6e5cf159943f5f46b65148978924d7f49bab13392fafd8b168d8 failed: retries exhausted after 6 attempts, with error: The "path" argument must be of type string. Received undefined
** Website deploys OK if no target is created **
Problem was solved by running firebase init. Issue was generated by cli update.
When I run firebase emulators:start I have this error
Error: Cannot start the Storage emulator without rules file specified
In firebase.json
Before installing Storage emulator, I can set the rule for Firestore like this
{
"firestore": {
"rules": "./functions/firestore.rules"
},
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
]
},
"emulators": {
"auth": {
"port": 9099
},
"functions": {
"port": 5001
},
"firestore": {
"port": 8080
},
"storage": {
"port": 9199
},
"ui": {
"enabled": true
}
}
}
I believe I have to set the rule for storage in here. But I don't know how. I can't find the docs for this
The error you're seeing is caused by a missing storage rules file. The solution is very similar to the way you set rules for Firestore.
Create a file called storage.rules in the same directory as firebase.json.
Add the following lines to it:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
Specify the rules file for the storage emulator in your firebase.json:
"emulators": {
"storage": {
"port": 9199,
"rules": "storage.rules"
},
}
Now, it's ready to start emulators.
Update
Thank you everyone for warning about the change in the newer versions. With the latest version, storage.rules should be defined at the top level in your firebase.json:
"emulators": {
"storage": {
"port": 9199
},
},
"storage": {
"rules": "storage.rules"
}
I am using the Realtime Database and Functions for my Flutter app. I've set up local emulators for both Database and Functions, so I can test Functions locally without the deployment cost. Now I want to connect my Flutter app to these local emulators, but I am having some trouble finding out how to do it.
The FlutterFire docs describes how to do this for Firestore (https://firebase.flutter.dev/docs/firestore/usage#emulator-usage), but not for the Realtime Database. Surely there must be a way to connect to the emulators, even though I am using the Realtime Database?
I have tried the following:
String host = Platform.isAndroid ? '10.0.2.2:4000' : 'localhost:4000';
FirebaseDatabase database = FirebaseDatabase(
app: Firebase.app(),
databaseURL: host,
);
But that gives me the error:
Unhandled Exception: PlatformException(error, Invalid Firebase Database url specified: 10.0.2.2:4000, null)
I am using the firebase_core and firebase_database packages on pub.
Digging deeper into Firebase Java SDK, I've found that .useEmulator() only sets host and port for creating the databaseURL and in short is just a refactoring wrapper.
Code below should work with FlutterFire Realtime Database package:
String host = Platform.isAndroid ? 'http://10.0.2.2:9000' : 'http://localhost:9000';
FirebaseDatabase database = FirebaseDatabase(
app: Firebase.app(),
databaseURL: host,
);
Also, do check your firebase.json for the correct port to use. Default should be 9000 for database.
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
],
"source": "functions"
},
"storage": {
"rules": "storage.rules"
},
"emulators": {
"auth": {
"port": 9099
},
"functions": {
"port": 5001
},
"firestore": {
"port": 8080
},
"database": {
"port": 9000
},
"ui": {
"enabled": true
}
}
}
According to the Firebase documentation for Android, using the Realtime Database emulator requires a call database.useEmulator("10.0.2.2", 9000). A quick search of the FlutterFire code shows no such calls, so it seems that emulator usage isn't implemented in FlutterFire yet.
I also couldn't find an open issue for it, so you might want to file a feature request.
Following code worked for me. Its almost similar to #Florin Stan answer. Just the namespace of the database was missing.
String host = Platform.isAndroid ? 'http://10.0.2.2:9000' : 'http://localhost:9000';
dbInstance= FirebaseDatabase(
databaseURL: '$host?ns=YOUR_DATABASE_NAMESPACE',
);
Database namespace can be found in firebase realtime database emulator UI.
I'm using deploy targets on Firebase and everything is working fine except my Cloud functions.
The process.env.FIREBASE_CONFIG env variable doesn't have the right values. The properties "databaseURL" and "storageBucket" are not the one I've configured the target to use
When I use admin.database() it doesn't use the right RTDB I've created and that I want to use
functions.storage.object().onFinalize() doesn't "watch" the right bucket
My .firebaserc file
{
"projects": {
"default": "hatch-rpg",
"dev": "hatch-rpg"
},
"targets": {
"hatch-rpg": {
"hosting": {
"shadra": [
"shadra"
]
},
"database": {
"shadra": [
"hatch-shadra-dev"
]
},
"storage": {
"shadra": [
"hatch-shadra-dev"
]
}
}
}
}
My firebase.json file
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"database": [
{ "target": "shadra", "rules": "database.rules.json" }
],
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
],
"source": "functions"
},
"hosting": [
{
"target": "shadra",
"public": "dist/shadra",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
],
"storage": [
{ "target": "shadra", "rules": "storage.rules" }
]
}
I'm initializing Firebase like this
admin.initializeApp(functions.config().firebase);
What am I missing ?
Thanks a lot
EDIT:
I have tried to override FIREBASE_CONFIG by doing firebase functions:config:set firebase.databaseURL="hatch-shadra-dev.firebaseio.com" firebase.storageBucket="hatch-shadra-dev" but it didn't worked because Invalid config name firebase.databaseURL, cannot use upper case. then tried without uppercase and got Cannot set to reserved namespace firebase
How can I override this FIREBASE_CONFIG ? or should I just not use it initialize manually firebase ?
Ok, here's what I did to fix this issue.
Maybe there's a better option or I'm just mis-using Firebase here.
Anyway, heres' the solution:
First, add some config to the project
firebase functions:config:set target.database="hatch-shadra-dev.firebaseio.com" target.bucket="hatch-shadra-dev"
Then use it in the Cloud function with admin.initializeApp()
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
const config = functions.config();
admin.initializeApp({
...config.firebase,
storageBucket: config.target.bucket,
databaseURL: `https://${config.target.database}`
});