Java FieldBDB警告:“使用未指定的索引。考虑添加”“索引”以获得更好的性能。

Java FieldBDB警告:“使用未指定的索引。考虑添加”“索引”以获得更好的性能。,java,android,json,firebase,firebase-realtime-database,Java,Android,Json,Firebase,Firebase Realtime Database,使用Firebase实时数据库运行Android应用程序时,我收到以下警告: 使用未指定的索引。考虑将Addio.Noxon…添加到您的安全性和FielBASE数据库规则中以获得更好的性能< /P> 我完全理解这个警告。但我不知道如何让它变得更好。我真的只想查询索引字段 这是我的数据库: { "groupUsers" : { "g1" : { "u1" : "admin" }, "g2" : { "u1" : "admin",

使用Firebase实时数据库运行Android应用程序时,我收到以下警告:

使用未指定的索引。考虑将Addio.Noxon…添加到您的安全性和FielBASE数据库规则中以获得更好的性能< /P> 我完全理解这个警告。但我不知道如何让它变得更好。我真的只想查询索引字段

这是我的数据库:

{      
  "groupUsers" : {
    "g1" : {
      "u1" : "admin"
    },
    "g2" : {
      "u1" : "admin",
      "u2" : "readonly"
    }
  },
  "groups" : {    
    "g1" : {
      "areas" : {
        "a1" : {
          "groupId" : "g1",
          "name" : "My Group"
        }
      },
      "interests" : {
        "i1" : {
          "groupId" : "g1",
          "name" : "My Interest"
        }
      },
      "points" : {
        "p1" : {
          "address" : "First Street",
          "areaId" : "a1",
          "groupId" : "g1",
          "latitude" : -25,
          "longitude" : -55,
          "name" : "Harry"
        }
      },
      "properties" : {
        "name" : "My Group Name"
      },
      "waypoints" : {
        "w1" : {
          "areaId" : "a1",
          "groupId" : "g1"
        }
      }
    }
  }
  "users" : {
    "u1" : {
      "email" : "some@domain.com",
      "firstName" : "Peter",
      "lastName" : "Smith"
    },
    "u2" : {
      "email" : "other@email.com",
      "firstName" : "John",
      "lastName" : "Wayne"
    }
  }
}
以下是我的安全规则:

{
  "rules": {       
    "groups": {          
      "$groupId": {
        ".read":  "root.child('groupUsers').child($groupId).child(auth.uid).exists()",
        ".write": "! root.child('groupUsers').child($groupId).exists() || root.child('groupUsers').child($groupId).child(auth.uid).val() === 'admin'",
        "$child": {
          ".write": "root.child('groupUsers').child($groupId).child(auth.uid).exists() && root.child('groupUsers').child($groupId).child(auth.uid).val() !== 'readonly' && ($child === 'points' || $child === 'visits')"
        }
      },

      "areas": {        
        ".indexOn": ["groupId", "name"]
      },
        "waypoints": {
        ".indexOn": ["groupId", "areaId", "sequenceNumber"]
      },
      "interests": {
        ".indexOn": ["groupId", "rank", "name"]
      },
      "points": {        
        ".indexOn": ["groupId", "areaId", "name"]
      },
      "visits": {
        ".indexOn": ["groupId", "pointId", "interestId", "userId"] 
      }
    },
    "users": {
      ".read": "auth != null",
      "$userId": {        
        ".write": "auth != null && $userId === auth.uid && newData.val() != null",
        ".indexOn": ["email", "firstName", "lastName"]
      }
    },
    "groupUsers": {
      ".read": "auth != null",
      "$groupId": {
        ".write": "auth != null && (root.child('groupUsers').child($groupId).child(auth.uid).val() === 'admin' || !root.child('groupUsers').child($groupId).exists())"
      }
    }
  }
}
问题是groupUser结构。它将组键作为属性名。我没有可索引的字段,因为我没有常量属性名。
如何更改结构以使所有字段都被索引并且我的所有规则仍然有效?

我不是Firebase的专家,但在我看来,您的安全规则似乎存在问题。特别是在“组”部分中,您引用了名为“名称”的字段作为索引,但此字段不是gr的直接字段oup对象。“名称”是properties对象的字段,因此您的组配置应为:

.indexOn:[属性/名称]

.indexOn:属性/名称

如您所见,Firebase保留了“/”字符,用于在对象的嵌套字段中导航,以用作索引

如果在默认情况下访问属性字段,并且这是FireBase的一个隐式特征,请跳过我的回答的这一部分

我认为,如果我们要将关系objectuser/group表示为警告的来源,我们至少需要正确地优化其余的对象索引,然后也许我们可以稍微重新设计关系表,以合并内部的可索引字段

实体关系结构的优化:

对于实体关系表groupUser,一个建议是将其合并到组表中。在组内添加groupUsers字段。该字段将由一个数组组成,每个数组条目都是一个用户对象。这种方法的唯一问题是需要以某种方式指定用户之间的外键关系这些条目与我们在关系表中所做的一样,是为了利用级联操作。示例更改:

    "groups" : {    
        "g1" : {
          "areas" : {
            "a1" : {
              "groupId" : "g1",
              "name" : "My Group"
            }
          },
          "groupUsers" : [
             {"userID" : "u1"},
             {"userID" : "u2"}],...
}
或使用非阵列解决方案:

    "groups" : {    
        "g1" : {
          "areas" : {
            "a1" : {
              "groupId" : "g1",
              "name" : "My Group"
            }
          },
          "groupUsers" : {
              "r1" : {"userID" : "u1"},
              "r2" : {"userID" : "u2"}
           },...
}

我试着回答你的问题,我明白了你的观点,你没有键名来设置索引,正如我们可以使用的那样。value在这里添加值的索引

下面可能适合您,在groupUsers中的用户角色级别添加了.value,因为这似乎是您可以设置索引的唯一字符串valueuser角色

"groupUsers": {
  ".read": "auth != null",
  "$groupId": {
    ".write": "auth != null && (root.child('groupUsers').child($groupId).child(auth.uid).val() === 'admin' || !root.child('groupUsers').child($groupId).exists())"
    ".indexOn": ".value"
  }
}

你是对的,对名称进行索引是没有意义的,因为它在属性中。但这与我的问题没有任何关系。无论如何,谢谢。我从规则文件中删除了那个不重要的部分。我不会说这没有意义,只是你当前引用的是一个不存在的字段group/name,而不是group/properties/name、 我将更新我的回复,希望它能进一步帮助您解决实体关系问题。好主意,但这只在值是标量的情况下有效。但在我的情况下,它们是键值对。在groupId下,您只有admin和readonly作为值,它们不是键值对。不,我有userid:admin,这是一个键值对。我尝试了它-它不起作用。好的,我刚才说的是groupId有键值对,但是。值只对值起作用,它会忽略你的例子中的键值u1,u2…等等。这和例子中的一样,恐龙的名字不同,但索引在值上是的。是的,我看到了那个例子,但遗憾的是它不一样。如果你仔细看,你会看到这一点它确实忽略键,但我的结构是key:key:value,而不是key:value。