Only authenticated users are permitted to write to Firebase databases

Currently, I am in the process of setting up a new Vue JS project for a blog with Firebase integration. The main objective is to allow any logged-in user to create blog posts that are saved in the Firebase real-time database at

https://xxx.firebaseio.com/blogs.json
, each with a unique Firebase ID.

The challenge I am facing is related to traditional Firebase rules where blog posts created by multiple users end up under their respective user IDs. This results in difficulty when using v-for to iterate over the blog posts as they are segregated under different user objects.

Shown below are my current Firebase rules:

{
  "rules": {
    "blogs": {
      ".read": true,
      ".write": false,
      "$uid": {
        ".read": "$uid === auth.uid",
        ".write": "$uid === auth.uid"
      }
    }
  }
}

I would like to have all blog posts created under one common location - blogs, rather than individual user IDs like $uid. How can this be achieved?

My current rule configuration outputs data structure as shown below:

{
    "PvWsi3t9mFZza5gXP8qNQaCktDN2": {
      "-LrZ87XS02DanBTybhij": {
        "body": "<p><strong>test</strong></p>",
        "creation": "",
        "slug": "test",
        "title": "My very first blog post"
      },
      "-LrZ8KjsJyGT1YFsIJ3G": {
        "body": "<p><strong>jjj</strong></p>",
        "creation": "2019-10-19",
        "slug": "test-2",
        "title": "Second post"
      }
    },
    "yLLOq9jC5odefHBENkO3r2ztNzZ2": {
      "-LrZ8ZRhLVEylBFaGcnq": {
        "body": "<p>content here</p>",
        "creation": "2019-10-04",
        "slug": "test-two",
        "title": "My very first blog post - ryan"
      }
    }
  }

UPDATE

Below is the Firebase reference used to add a blog post:

firebase.database().ref('blogs/' + this.$store.state.user.uid).push(this.post).then(() => {
         console.log('success')
      }).catch((err) => {
         console.log('error', err)
      })

Answer №1

When implementing rules like the following (not yet tested):

"rules": {
    "blogs": {
        ".read": true,
        "$blogId": {
            ".write": "(!data.exists() || data.child('author').val() == auth.uid)
                    && (newData.child('author').val() == auth.uid || !newData.exists())"
        }
    }
}

You can opt for a flat structure for your blogs by including an author field and ensuring it matches the creator's UID.

The first line under ".write" implies "it's either a new blog or belongs to YOU".

The second line signifies "it is now YOUR blog or it has been deleted".

Your code snippet should resemble this:

const postWithAuthor = this.post;
postWithAuthor.author = this.$store.state.user.uid;
firebase.database().ref('blogs').push(postWithAuthor).then(() => {
    console.log('success');
}).catch((err) => {
    console.log('error', err);
});

If you are worried that exposing UIDs could lead to unauthorized database writes, consider that revealing your identity online opens up similar risks. The rule

newData.child('author').val() == auth.uid
ensures that anyone claiming to be X must also authenticate as X in order to write to your database using their real UID as the author.

To restrict writing access to only certain individuals, store their UIDs in the database, possibly in the "admins" path, and add

&& root.child('admins/'+auth.uid).exists()

to your ".write" rules.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

extracting a JSON array from an API

I'm trying to extract the title from my API using JavaScript and then display it in HTML. api:(https://k0wa1un85b.execute-api.us-east-1.amazonaws.com/production/books) The JSON response is as follows: {"statusCode":200,"body":[{"id":"4f160b1f8693cd ...

A guide to verifying a user's age using JavaScript by collecting information from 3 separate input fields

On page load, only the year input is required for users to fill in. The user can enter their birth year first without providing the month and day. Currently, I have a function that checks if a person is over 16 years old by comparing their birth year with ...

Deactivate checkbox based on dropdown selection

I'm facing an issue where I need to disable a checkbox when a certain option is selected from a dropdown inside a datatable in my xhtml file. The dropdown has options like L, C, UV, and more, and when "L" is chosen, the checkbox should be disabled. B ...

Utilizing ajax for fetching a data table

I am new to using ajax and have successfully retrieved data from a table. However, I am now trying to pull in an entire data grid but not sure how to achieve this. In my index.php file, I have the following code: <html> <head><title>Aj ...

Steps to fix the Error: connect EISCONN ::1:5555 - Local (:ffff.127.0.0.1:5555)

Currently, I am in the process of developing an Electron app where I need to establish a connection with a TCP port on my local machine. However, upon starting the application, I encounter the following error message: "A JavaScript error occurred in the ma ...

Example of material-ui-pickers: Error - Object(...) is not a function

Trying to implement a basic material UI pickers example using a clean project and following the installation and usage instructions provided here: An error message is displayed as follows: TypeError: Object(...) is not a function Module../node_modules/@m ...

What is the process for generating a watermark directive in angularjs?

My application utilizes a jQuery script for watermarking textboxes. I created a directive to easily apply this watermark to input elements, but it's not functioning as expected. While debugging, I can see the watermark being added, but once the UI fin ...

Is it possible to refactor this forwardRef so that it can be easily reused in a function?

Currently, I am in the process of transitioning my application to Material UI V4 and facing challenges with moving my react router Link components into forwardRef wrapped components when setting the 'to' prop programmatically. The code below doe ...

Capture every incoming request with various HTTP methods using nock

Check out the updated intercept function below: interceptWithError() { nock(baseUrl) .get(/.*/) .replyWithError(500); nock(baseUrl) .put(/.*/) .replyWithError(500); nock(baseUrl) .post(/.*/) .replyWithError(500); nock(ba ...

What is the best way to retrieve a Rails variable that is restricted to a specific partial?

As a newcomer to Ruby on Rails, I find myself struggling to grasp the larger concept. Any assistance you can offer would be greatly appreciated. Within my application.html.haml file, I utilize =yield to pull content from ranked.html.haml. Currently, this ...

Issue with pagination not functioning properly when using search functionality in vue-good-table

When using Vue-good-table remote search, I encountered an issue while searching on the second page. The search page automatically sets to the second page, but the pagination remains on the first page. I attempted to manually set the page using setCurrentPa ...

Retrieving Data from a Nested JSON Array

How do I modify my JavaScript code to extract the last 3 values from the JSON list provided below? The current code is unable to read these values with different formatting. Example section of the JSON list: {...... 'Design_Lump_Sum': {0: {&a ...

Error: Unable to access the 'classList' property of null in HTMLSpanElement.expand function

Encountering a minor issue with my javascript code. Following a tutorial for a seemingly simple task: link What I did: Adapted the HTML from the tutorial to fit my desired visual outcome while maintaining correct class and id attributes. Utilized identic ...

use ".otherwise" or /** with the latest version of Angular2 Router to redirect non-routes using wildcards

Can anyone provide guidance on using wild cards to route in the new Router when a non functional route is specified? Similar to the .otherwise method in Angular 1.X router or /** in previous beta router. Additionally, any example or Plunker code would be ...

Laravel's Vue component is experiencing issues with loading Axios response data

Hey everyone, I hope you're all doing well! I'm facing a bit of an issue with passing data from an axios response to the data property. The data is successfully fetched from the database and displayed in the console, but when I try to display it ...

Setting up Jest configuration for integrating supertest with Vue framework

I have a unique application that utilizes both vue and express. I have separate tests for each, allowing me to run either a vue test or an express test independently. Below is the customized jest config file. This configuration works perfectly for Vue tes ...

When rendering, DirectionsRenderer replaces the Marker

I'm currently working on implementing a real-time tracking system for customers to track their deliveries. I have succeeded in setting up markers for the destination and pickup locations, as well as a route path towards them. However, I encountered an ...

Reorganizing objects upon insertion in Mongo DB

I am encountering an issue in my Node.js app where MongoDB is causing objects to be reordered when inserting new records into the database. I am using the following insert method: collection.insert(object, {safe:true}, function(err, result) { if (err) ...

Utilizing only JavaScript to parse JSON data

I couldn't find a similar question that was detailed enough. Currently, I have an ajax call that accesses a php page and receives the response: echo json_encode($cUrl_c->temp_results); This response looks something like this: {"key":"value", "k ...

Showing items in a VueJS component and transferring them to the component

Utilizing VueJS 2.0 and vue-router 2, my goal is to display a template based on route parameters. I have a view called WidgetView where components are dynamically changed. Initially, WidgetComponent is shown which displays a list of widgets. When a user se ...