Firestore Rules coverage report - Request expression never evaluated - firebase

Recently I have been using firebase for my new app. Since you can define your own rules on firestore, I wanted to try that out.
To test these rules I am running the firestore emulator. When I try to authorize some test user I always get a timeout error. Wanting to solve the error by myself I've made some research.
I have found out that it is possible to see the "Firestore Rule Coverage Report" and inside there I've seen this:
But since I am new to firestore I did not know what this is and also after some googling I didn't find out how to solve this problem.

Firestore docs are a bit confusing. They state that the URL should be:
http://localhost:8080/emulator/v1/projects/<database_name>:ruleCoverage.html
However, they don't explain what <database_name> should be replaced with your project_id. Yes... reading the URL some might thing is obvious, but is really the argument name that should make it obvious. Plus, in Firestore databases are not created neither accessed by name.
SOLUTION:
<database_name> should be replaced by your project_id (this value is available in the files .firebaserc or google-services.json
So, if your project_id is my-amazing-app, your rulesCoverage url would be:
http://localhost:8080/emulator/v1/projects/my-amazing-app:ruleCoverage.html

My problem was that I executed loadFirestoreRules before every test. I changed it to run loadFirestoreRules only one time for all tests, and now it's working.

I followed the examples from https://github.com/firebase/quickstart-testing . Bu two examples for security rules, only the example for version 8 at https://github.com/firebase/quickstart-testing/tree/master/unit-test-security-rules is working. Although I am using JS SDK v9, but using the example for version 8 can help me testing my security rules just fine.

I suspect the root of the problem is that the expression is throwing an error. If the user isn't authenticated then request.auth will be null (and therefore request.auth.uid will throw a null reference error).

Related

Firebase Admin SDK Not Reading, Writing, or Throwing Errors (Node.js)

This question was previously closed, telling me to "update the question so it focuses on one problem only;" I don't know what the problem is, and if I did, I wouldn't be posting this question. Regardless, I'll make some clarifications here:
I was previously using just the normal Firebase module (the one imported using "npm i firebase"); everything worked perfectly before. The issue has to do with the authentication (as far as I am aware) with the Firebase Admin SDK. I don't understand how I'm supposed to send this to the Heroku build without revealing the service account key JSON file on my GitHub.
As for the GOOGLE_APPLICATION_CREDENTIALS path, is there a way where I don't have to set it every session? The Heroku app restarts once a day, and I would need to somehow automate this entry process (or skip it entirely). That's the way I currently understand it. Here's a quote from a previous answer:
When I set the GOOGLE_APPLICATION_CREDENTIALS path, doesn't this only set it on my local machine?
Environment variables only work on the individual machine and process where they have been set. If you want it set on another machine and process, you will have to arrange for that separately. According to the documentation:
Set the environment variable GOOGLE_APPLICATION_CREDENTIALS to the file path of the JSON file that contains your service account key. This variable only applies to your current shell session, so if you open a new session, set the variable again.
My main question here is as follows: "I implemented the Firebase Admin SDK incorrectly. How do I do it the right way?"
Even just posting a link to guides that would help would be appreciated (although I understand this is typically discouraged as links sometimes break).
Original:
Note: this is my first time using the Firebase Admin SDK, so I'm really not sure what I'm doing (although I have used Firebase quite a bit).
Recently, I decided I would go back to one of my older Discord bots and actually authenticate its requests to Firebase properly (I hadn't done this previously as I've never authenticated from a server before and didn't think it was possible). I discovered the Firebase Admin SDK, which sounded perfect for my needs (the bot is being hosted on Heroku, for the record).
I found this guide: https://firebase.google.com/docs/admin/setup, but there's a few things I can't wrap my head around (note that these are purely rhetorical, you don't need to answer them in your answer; I'm just providing them so you can understand my thought process):
When I set the GOOGLE_APPLICATION_CREDENTIALS path, doesn't this only set it on my local machine? I could also try running the export command on the server (using "heroku run" in the CLI), but then the path would be pointing to a file that doesn't exist on the server (since the service account key JSON file is on my local machine). Do I need to set an environment variable in Heroku or something?
How does "admin.credential.applicationDefault()" know how to get the credentials?
I can't find any other guides that make sense.
The way I currently have it setup must be wrong, since reads and writes fail silently.
Firebase setup code:
// Setup Firebase:
const admin = require('firebase-admin');
// Initialize Firebase:
admin.initializeApp({
credential: admin.credential.applicationDefault(),
databaseURL: "https://<APP>.firebaseio.com" // I removed the actual <APP> name to ask this question
});
let database = admin.database();
Things like database.ref("test").set("Hello World!"); don't change the data in the database, and no errors are thrown (I've also tried attaching a .then and a .catch to the end of this; still nothing). This was working before I switched over to the Firebase Admin SDK (I was just using the "firebase" module previously, rather than the "firebase-admin" module that I'm now using). The same goes for reading data.
Any help would be appreciated.
Here was my problem:
I was sending res.status(200) outside of the async firebase call, killing the request before firebase had a chance to finish. Somehow localhost allows this to work properly but when its hosted things go sideways.
so I had this
fireabse.database().ref('parent/foo').set('bar');
res.status(200)
I needed this:
firebase.database().ref('parent/foo').set('bar').then(() => {
res.status(200);
});

Type query_root must define one or more fields

First, thanks Hasura for incredible good product! I love it.
I have issue with derive action with Hasura Console. My use case:
I enable anonymous role for subscribe function (everybody can send email to subscribe)
I have configured permission on my subscribe table, everything is fine.
I want to validate the user input on server side, for example, validate email format. I have followed by this guide about derive action. I found no mistake here.
But I got the error "Type query_root must define one or more fields." when I hit "Derive action" at the first time.
According to this question, as I understand, I need to have object type for root query.
Of course, I will have object type for root query eventually. I can work around by giving some dummy queries for anonymous role. But I do not like that cheat anyway.
Any idea on that? Any help will be highly appreciated.
Edited:
My related current version:
Hasura 1.3.2
One click deployment using Docker on Digital Ocean.

firestore security rules request.auth.uid == userId kept returning 'Simulated read denied'

I'm trying to get request.auth.uid == userId to be tested but I'm getting 'Simulated read denied'.
I checked all of the basic questions before inputting this issue -
Did you deploy security rules?
I deployed the rules via the fireconsole (clicking the publish button and waiting for a min).
Did you have loggedin using Firebase Authentication?
I haven't implemented this work, I'm trying to test the security rules via using simulator in console.
I tried basic rule below and it works fine.
if request.auth.uid != null;
Here are the screenshots of my testing -
When using the security rules simulator, you need to enter the exact, full path of the document to read. You can't use wildcards. Right now, you're trying to using a wildcard in the document path: "/users/{userId}" This isn't going to work. This makes the userId variable in your rules become literally the string "{userId}". What you need to do instead is paste the actual ID of the document you want to test for reading into the form. This is going to be the UID starting with "JoF".
BTW: You are not required to deploy rules in order to test them in the simulator. You can choose to deploy them only after you've tested them.

firebase logging best practice

I'm looking for a way to log everything that is written on a firebase database. For now, I'm using a few firebase functions that are simply printing a diff between old values and new ones. However I'm not sure the firebase functions logs screen is the best tool in this situation. Do you have any recommendations?
I had a similar problem and I ended up adding database triggers in which I send data to another firebase database (using the production one is not recommended) which stored the logs in the following form:
logs:{
myFunction:{
'10.01.2018': {
debug: 'Some logging here',
error: 'Some error here'
}
}
}
I found a way.
I'm still using firebase functions to log a diff of the previous and current values of objects written on my database.
I'm now using stackdriver logging from google cloud platform to visualize the logs, and this tool is what I was looking for.

basic firebase URL structure?

I am building a very simple cron job backup system for a friend's firebase app;
I have PHP code, using firebase-php that can communicate with the firebase and the API docs state that adding the'?format=export" parameter will retrieve a .json file. Cool, so far.
My question is this: What path (after the firebase URL) is required?
The API doc appears to state that it should be /.json but it returns a 404 /json/ works on the simulator, but also returns a 404 in testing
(note: looking for a single text file, similar to the "Export json" data dashboard, if possible)
Thanks in advance.
The path defined the portion of the Firebase data tree that is being loaded. That means that you can load /any/possible/string and it will return a value, though that value is likely to be null unless you've written data to that path. Also note that without a defined extension (i.e. .json) you'll be attempting to load Firebase's in-browser graphical debugger.
In short, if you're using the REST API, you'll always want to end your paths in .json, but nothing else is required, i.e. https://<your-firebase>.firebaseio.com/.json is perfectly valid, and would download your entire Firebase. The format=export parameter ensures that any Firebase priority values are preserved in your JSON output, under the key .priority at any node, where they would normally be excluded.

Resources