0
votes

I'm actually building a react-native & firebase group chat and I need to separate users in there proper channels. I have 6 channels with there proper chat and I don't want the fact that a user can create his channel. In my app, I want to authorize the access to 5 users in Group A, 8 users in B group, etc. I currently have a firebase database that look like this

Firebase Database

and my rules are :

{
  "rules": {
    "GeneralMessage": {
      ".read": "root.child('user').child(auth.uid).child('inGeneral').child('GeneralMessage').child('read').val() === true",
      ".write": "root.child('user').child(auth.uid).child('inGeneral').child('GeneralMessage').child('write').val() === true"
    }
  }
}

But this don't let me access to read and write options.

Edit: The react native code where I push the chat in room.

import * as types from './actionTypes'
import firebaseService from '../../services/firebase'

const FIREBASE_REF_MESSAGES = firebaseService.database().ref('/GeneralMessage')
const FIREBASE_REF_MESSAGES_LIMIT = 20

export const sendMessage = message => {
  return (dispatch) => {
    dispatch(chatMessageLoading())

    let currentUser = firebaseService.auth().currentUser
    let createdAt = new Date().getTime()
    let chatMessage = {
      text: message,
      createdAt: createdAt,
      user: {
        id: currentUser.uid,
        email: currentUser.email,
      }
    }

    FIREBASE_REF_MESSAGES.push().set(chatMessage, (error) => {
      if (error) {
        dispatch(chatMessageError(error.message))
      } else {
        dispatch(chatMessageSuccess())
      }
    })
  }
}

export const updateMessage = text => {
  return (dispatch) => {
    dispatch(chatUpdateMessage(text))
  }
}

export const loadMessages = () => {
  return (dispatch) => {
    FIREBASE_REF_MESSAGES.limitToLast(FIREBASE_REF_MESSAGES_LIMIT).on('value', (snapshot) => {
      dispatch(loadMessagesSuccess(snapshot.val()))
    }, (errorObject) => {
      dispatch(loadMessagesError(errorObject.message))
    })
  }
}


const chatMessageLoading = () => ({
  type: types.CHAT_MESSAGE_LOADING
})

const chatMessageSuccess = () => ({
  type: types.CHAT_MESSAGE_SUCCESS
})

const chatMessageError = error => ({
  type: types.CHAT_MESSAGE_ERROR,
  error
})

const chatUpdateMessage = text => ({
  type: types.CHAT_MESSAGE_UPDATE,
  text
})

const loadMessagesSuccess = messages => ({
  type: types.CHAT_LOAD_MESSAGES_SUCCESS,
  messages
})

const loadMessagesError = error => ({
  type: types.CHAT_LOAD_MESSAGES_ERROR,
  error
})
1
The react-native code ? - Jats1596
I've just edited my post, but I think that's not the problem. The problem is when i define my rules maybe. - Jats1596
In cases involving security rules it's often better to have the complete picture. A lot of times it's a simple mismatch between the rules and read/write code. In your case I think it's a mismatch between your datastructure and rules I think. I will write up an answer in a couple mins. - André Kool

1 Answers

1
votes

Your datastructure and security rules are not completely matching. You have a rule for /user/user.uid/inGeneral/GeneralMessage/read but there isn't a GeneralMessage child under inGeneral in your datastructure.

With your current datastrcuture your rules have to look like this:

{
  "rules": {
    "GeneralMessage": {
      ".read": "root.child('user').child(auth.uid).child('inGeneral').child('general').val() === true",
      ".write": "root.child('user').child(auth.uid).child('inGeneral').child('general').val() === true"
    }
  }
}