79400150

Date: 2025-01-30 14:06:22
Score: 1.5
Natty:
Report link

Thanks for very detailed answer!

To refer other comments too, my intention is exactly as you have mentioned; "give users the minimum requirements for both reading and writing, nothing more".

See my rules for users table (where user data that is needed for other purposes + User-Messages table).

{
  "rules": {
    ".read": false, // disables general read access
    ".write": false, // disables general write access

    "Users": {
      ".read": "auth != null", // Users can read all profiles
      
      "$userUid": {
        ".write": "auth != null && auth.uid === $userUid", // Users can write only their own data
        
        ".validate": "newData.child('userUid').val() === auth.uid && 
                      newData.child('userID').isNumber() && 
                      newData.child('userName').isString() && newData.child('userName').val().length > 0 && 
                      newData.child('userFCMToken').isString() && newData.child('userFCMToken').val().length > 0 &&
                      newData.child('userPhoneLanguage').isString() &&

                      newData.child('userProfileImage').isString() && 
                      newData.child('userProfileImage').val().matches(/^https:\\xxxxx\\//) &&

                      (!newData.child('userBusiness1Id').exists() || newData.child('userBusiness1Id').isNumber()) &&
                      (!newData.child('userBusiness1Name').exists() || 
                      (newData.child('userBusiness1Name').isString() && newData.child('userBusiness1Name').val().length > 0)) &&
                      (!newData.child('userBusiness1ProfileImage').exists() || 
                      (newData.child('userBusiness1ProfileImage').isString() && 
                      newData.child('userBusiness1ProfileImage').val().matches(/^https:\\/\\xxxxx\\//))) &&

                      (!newData.child('userBusiness2Id').exists() || newData.child('userBusiness2Id').isNumber()) &&
                      (!newData.child('userBusiness2Name').exists() || 
                      (newData.child('userBusiness2Name').isString() && newData.child('userBusiness2Name').val().length > 0)) &&
                      (!newData.child('userBusiness2ProfileImage').exists() || 
                      (newData.child('userBusiness2ProfileImage').isString() && 
                      newData.child('userBusiness2ProfileImage').val().matches(/^https:\\/\\/xxxxxx\\//)))"
      }
    },
     "User-Messages": {
        ".write": "auth != null",
        ".read": "auth != null",
    },

I have tried your approach but couldn't figure it out how to define fromId, toId or pushId..

    func sendMessage(text: String, fromId: String, toId: String) {
    let trimmedText = text.trimmingCharacters(in: .whitespacesAndNewlines)
    if trimmedText.isEmpty { return }
    
    let timeStamp = Int64(Date().timeIntervalSince1970)
    
    let reference = Database.database().reference().child("User-Messages").child(fromId).child(toId).childByAutoId()
    let toReference = Database.database().reference().child("User-Messages").child(toId).child(fromId).childByAutoId()
    
    let chatModel = ChatModel(chatId: reference.key, text: trimmedText, fromId: fromId, toId: toId, timestamp: timeStamp, messageIsRead: true)
    let chatModelForRecipient = ChatModel(chatId: toReference.key, text: trimmedText, fromId: fromId, toId: toId, timestamp: timeStamp, messageIsRead: false)
    
    reference.setValue(chatModel.toDictionary())
    toReference.setValue(chatModelForRecipient.toDictionary())

}

This is the full code that how i post data into User-Messages.

I combine fromId or toId inside the view before calling sendMessage, as userUid_businessId.

I simply couldn't figure this out how should i define inside the rules where users can write/read since it is dynamic.

so sender should be able to write for both paths : user itself + message receiver.

Thanks!

Reasons:
  • Blacklisted phrase (0.5): Thanks
  • Blacklisted phrase (1): how should i
  • Long answer (-1):
  • Has code block (-0.5):
  • Self-answer (0.5):
  • Low reputation (1):
Posted by: S.S.S