Realtime database emulator ignores database.rules.json - firebase

I have a Firebase project that uses the realtime database, and I'm trying to set up the local emulator for testing. Unfortunately, it seems that the Firebase-cli is ingoring my database.rules.json file. This happens even after creating a test project to solve this specific problem.
Let me give you some info about my setup.
I created a Firebase project with nothing enabled. I created an empty directory on my local machine and ran firebase init database. Doing that created a few files:
.firebaserc
{
"projects": {
"default": "emulators-test-244be"
}
}
firebase.json
{
"database": {
"rules": "database.rules.json"
}
}
database.rules.json (I modified the rules here to lock down the database)
{
"rules": {
".read": false,
".write": false
}
}
When I run the emulator using firebase emulators:start --only database, the console tells me that the database successfully initializes. However, when I visit http://localhost:9000/.inspect/coverage?ns=emulators-test-244be to view the currently loaded security rules, it gives the following output:
{
"rules": {
".read": true,
".write": true
}
}
Obviously, this directly contradicts the rules I have set in the database.rules.json file.
One thing I did notice, is that if I modify the database.rules.json file while the emulator is running, I get the following output from the console:
i database: Change detected, updating rules for undefined...
Apparently, doing this causes the emulator to create a new database called undefined. When I go to http://localhost:9000/.inspect/coverage?ns=undefined, the output correctly reflects what I have set in my database.rules.json file.
Why is this happening? Am I incorrectly setting up my local Firebase project? Or is there a bug in the Firebase CLI? I've scoured the Firebase docs, Stack Overflow, and Google. I haven't found anything.
I have firebase tools version 8.4.3.
UPDATE
After searching through the issues on the firebase-tools GitHub repo, it seems that this is a bug.
Link here:
https://github.com/firebase/firebase-tools/issues/2371

This workaround worked for me:
.firebaserc
{
"projects": {
"default": "emulators-test-244be"
},
"targets": {
"emulators-test-244be": {
"database": {
"default": [
"emulators-test-244be"
]
}
}
}
}
firebase.json
{
"database": [
{
"target": "default",
"rules": "database.rules.json"
}
],
"emulators": {
"database": {
"port": 9000
},
"ui": {
"enabled": true,
"port": 4000
}
}
}
When I start the emulator with firebase emulators:start and visit: http://localhost:9000/.inspect/coverage?ns=emulators-test-244be I get the rules specified in my database.rules.json file.
Hope it also works for others with this problem.

Related

Running Firebase Deploy gives JSON error trying to load file

Getting an error when deploying to firebase. I manually edited .firebaserc file to add other projects.
$ firebase deploy --project staging --only hosting:admin
⚠ JSON error trying to load /some/path/to/.firebaserc
.firebaserc
{
"projects": {
"production": "myapp-8879",
"staging": "myapp-c8499"
},
"targets": {
"myapp-8879": {
"admin": [
"admin-app"
],
"app": [
"myapp-8879"
],
},
"myapp-c8499": {
"admin": [
"admin-app"
],
"app": [
"myapp-c8499"
]
}
}
}
To solve this problem, JSON error trying to load /some/path/.firebaserc you must make sure JSON format is correct.
.firebaserc
There is an extra comma, so firebase deploy will throw an error.
If you manually edit your .firebaserc on VSCODE then just change the Language Mode to JSON or use any online json formatter tool.

How to unalias the default Firebase project?

After unaliasing my "default" project, Firebase still uses it:
> firebase use --unalias default
Removed alias default
Run firebase use --add to define a new project alias.
> firebase deploy
=== Deploying to 'myproject0'...
My code base is deployed on multiple projects that I use as separate environments. I would like to explicitly specify the project for all my Firebase CLI commands to avoid messing with production or staging environments.
Is it not possible to unalias the default project?
Am I doing it wrong?
My .firebaserc is successfully updated:
{
"projects": {
"production": "myproject0",
"test": "myproject-test"
},
"targets": {
"myproject0": {
"hosting": {
"superadmin-webapp": [
"superadmin-myproject0"
],
"client-webapp": [
"myproject"
]
}
}
}
}

How do I connect to my local Realtime Database emulator in my Flutter app?

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.

Firebase: deploy same app to multiple Firebase-projects

I´m trying to deploy my code to two different Firebase-projects, one for development and one for production.
The my-app-dev project was already included and working, so I added the my-app (for production) with firebase use --add and selected the my-app.
This is how my Firebase-config looks now:
.firebaserc
{
"targets": {
"my-app-dev": {
"hosting": {
"app": [
"my-app-dev"
]
}
}
},
"projects": {
"default": "my-app-dev",
"prod": "my-app"
}
}
firebase.json
{
"hosting": [
{
"target": "app",
"public": "dist/app",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
],
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
]
}
}
As long as I deploy to my default project, everything works fine, but when I try to firebase deploy -P prod it shows the following error:
Deploy target app not configured for project my-app. Configure with:
firebase target:apply hosting app <resources...>
I tried to find some more information about this command, but still don´t know what to put for resources. Overall I feel like the .firebaserc has a very confusing structure.
I had the same problem but in a different fashion.
The project I have is an Angular 11 project, which has 4 different environments - the same behaviour of deploying to the default project (env) was fine but as soon as I tried to deploy to a different environment (firebase project), it failed with the same error:
Deploy target ___ not configured for project ___. Configure with:
I resolved this by adding to my .firebasesrc > targets:
{
"projects": {
"default": "default-project"
},
"targets": {
"default-project": {
"hosting": {
"frontend": [
"default-project"
]
}
},
"staging-project": { // Added this entry.
"hosting": {
"frontend": [
"staging-project"
]
}
}
}
}
According to this comment in GitHub it cannot be done without a "hacky" method like swapping the firebase.json programmatically during deploying.
Right now the Firebase CLI is built to treat projects as anonymous
environments that are functionally identical. This is important to be
able to deploy the same assets to multiple projects without having to
alter the code (including in firebase.json).
To achieve what you want, you'll need to set up a dev and prod folder,
each with their own firebase.json and each with a target only for that
specific project. Deploying different assets to different projects is
not supported now and is unlikely to be supported in the future
(however, we may allow configuring the location of firebase.json via a
flag at some point).

Error: Error reading rules file firestore.rules

I am trying to deploy my website while using Firebase as a host and deleted the firestore.rules file as I didn't think that I required the use of the Cloud Firestore database (I'm just deploying a placeholder for now).
I have followed all the steps as mentioned in their documentation.
When I run firebase deploy I get the error:
Error: Error reading rules file firestore.rules
I don't know how to move past this. Can someone please help me with a solution to this? Thank you!
How to retrieve your existing Cloud Firestore rules
Go to your Firebase Console and click on Cloud Firestore from the Build category in the sidebar.
You can see a Rules tab on the top of the screen (below the Cloud Firestore heading). Open the Rules tab. Now you can see the rules which are currently active and all the other ones you have deployed so far (via CLI or Firebase Console).
You can copy your rules from here and paste it in a file called firestore.rules in your project folder.
How to fix the error "Error: Error reading rules file firestore.rules"
This error will most likely appear if you have set a wrong path for the firestore.rules in your firebase.json file (e.g. moved the file to a subfolder) or you don't have a firestore.rules file at all but reference it in the firebase.json.
Wrong path set in firebase.json
Open your firebase.json file from your Firebase project folder. You can find some paths and filenames in this file.
Look for the firestore category. It should look similar to this:
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
You may want to update your paths or filenames to match where your firestore.rules are located.
If you can't find any paths for firestore you can add them to your firebase.json file. It may now look like this (note: I've moved my firestore files and changed the path of the firestore.rules and firestore.indexes.json):
{
"firestore": {
"rules": "firestore/firestore.rules",
"indexes": "firestore/firestore.indexes.json"
},
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
},
"functions": {
"predeploy": [
"npm --prefix \"$RESOURCE_DIR\" run lint",
"npm --prefix \"$RESOURCE_DIR\" run build"
],
"source": "functions"
}
}
If you don't want to deploy any Firestore rules from your project folder
If you want to deploy your Firestore rules just over the Firebase Console you can delete the firestore.rules and firestore.indexes.json files from your project folder and delete the firestore part from your firebase.json. Although I recommend to keep them in your project folder so you can keep track of them in your version control system.
Keep in mind that you may also just delete the reference in the firebase.json file that the rules aren't deployed via the CLI and keep the firestore.rules and firestore.indexes.json files.
Delete this if you don't want to deploy your Firestore rules via the CLI:
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
if you're following this tutorial
https://firebase.google.com/codelabs/firebase-web#14 then the issue here is when you try to deploy running this command firebase deploy --except functions then this script will try to look for files with firestore.rules and storage.rules in the root directory and you'll get the following Error: Error reading rules file storage.rules this file because you told to do so in.
So to deploy it successfully with firebase deploy --except functions then you have to create this files in root directory and then will work.
firebase.json file
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"storage": {
"rules": "storage.rules"
},
"hosting": {
"public": "./public",
"headers": [
{
"source": "**/*.#(js|html)",
"headers": [
{
"key": "Cache-Control",
"value": "max-age=0"
}
]
}
]
}
}
firestore.rules
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /messages/{messageId} {
allow read;
allow create, update: if request.auth != null
&& request.resource.data.name == request.auth.token.name
&& (request.resource.data.text is string
&& request.resource.data.text.size() <= 300
|| request.resource.data.imageUrl is string
&& request.resource.data.imageUrl.matches('https?://.*'));
allow delete: if false;
}
match /fcmTokens/{token} {
allow read: if false;
allow write;
}
}
}
storage.rules
// Returns true if the uploaded file is an image and its size is below the given number of MB.
function isImageBelowMaxSize(maxSizeMB) {
return request.resource.size < maxSizeMB * 1024 * 1024
&& request.resource.contentType.matches('image/.*');
}
service firebase.storage {
match /b/{bucket}/o {
match /{userId}/{messageId}/{fileName} {
allow write: if request.auth != null && request.auth.uid == userId && isImageBelowMaxSize(5);
allow read;
}
}
}
So with this 2 file firestore.rules and storage.rules added to root directory the deploy command should work.
Add the firestore.rules attribute pointing to firestore.rules
this what the dics at firebase website says:
then change:
{
// Add this!
"firestore": {
"rules": "firestore.rules"
},
to:
{
// Add this!
"firestore": {
"firestore.rules": "firestore.rules"
},
this worked for me
Follow these steps:
Go to firebase.json.
Add this code :
{
"hosting": {
"public": "./public",
"headers": [{
"source" : "**/*.#(js|html)",
"headers" : [ {
"key" : "Cache-Control",
"value" : "max-age=0"
} ]
}]
}
}
Run firebase deploy --except functions.
** PS **: I assume you already changed the rules in the Firebase dashboard.
delete :"rules": "firestore.rules", from firebase.json file

Resources