Search code examples
flutterfirebase-realtime-databasefirebase-security

Firebase Database rule for unknown child nodes


I'm creating a chat app where data are stored like the image given below.

I want to add a validation rule for "Text" to be less than 300 characters long. I used the validation rule:

"TextChannels":{
    "Anime_Weebs":{
    ".validate": "newData.child('Text').val().length < 200"
},

But this rule is not working. Instead any type of text is getting rejected.

This is my database:

Database SS

And this is my Flutter AddMessage code:

_addMessage() {
final user = FirebaseAuth.instance.currentUser;
final time = DateTime.now().toUtc().millisecondsSinceEpoch;
_dbRef
    .ref('TextChannels/${channelName}/Messages/')
    .child('${time.toString()}${user!.uid}')
    .set({
  'Author': user.displayName,
  'Author_ID': user.uid,
  'Author_Username': username,
  'Time': time,
  'Text': _message,
  'Delivered': false,
  'Day': days
});

}


Solution

  • This rule that you have:

    "TextChannels":{
      "Anime_Weebs":{
        ".validate": "newData.child('Text').val().length < 200"
      },
    

    This rule says that your database has a path TextChannels/Anime_Weebs that has a child node Text whose length you want to restrict. But if we look at your database, there is no path TextChannels/Anime_Weebs/Text - and since a non-existing value is definitely not longer than 200 characters, the rule doesn't block any write operation.


    If you want to apply a rule to all child nodes under a path, you need to use a wildcard variable to capture the unknown part of the path:

    "TextChannels":{
      "Anime_Weebs":{
        "Messages": {
          "$messageId": {
            ".validate": "newData.child('Text').val().length < 200"
          }
        }
      },
    

    So here the Messages and $messageId rules are new compared to your rules, and the latter indicates the the .validate rule should be applied to each child node of TextChannels/Anime_Weebs/Messages.