Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/213.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 将项目添加到Firebase数据库中的列表_Android_Firebase_Firebase Realtime Database - Fatal编程技术网

Android 将项目添加到Firebase数据库中的列表

Android 将项目添加到Firebase数据库中的列表,android,firebase,firebase-realtime-database,Android,Firebase,Firebase Realtime Database,我有以下Firebase数据库结构uid是列表的一种类型。我试图在uIds下添加另一个索引递增的uIdsetValue()和updateChildren()将要求我检索现有数据,push()将添加一个带有随机生成字符串的项作为键,而不是递增索引。是否有一种更简单的方法不需要检索现有数据?谢谢 "requests" : { "request001" : { "interests" : [ "x" ], "live" : true, "uIds" :

我有以下Firebase数据库结构
uid
列表的一种类型。我试图在
uIds
下添加另一个索引递增的uId
setValue()
updateChildren()
将要求我检索现有数据,
push()
将添加一个带有随机生成字符串的项作为键,而不是递增索引。是否有一种更简单的方法不需要检索现有数据?谢谢

  "requests" : {
    "request001" : {
      "interests" : [ "x" ],
      "live" : true,
      "uIds" : [ "user1" ]  // <---- from this
    },
    "request002" : {
      "interests" : [ "y" ],
      "live" : true,
      "uIds" : [ "user2" ]
    }
  }

但是我想知道这个过程是否有必要,因为我只是想在列表中添加一个项目
uid

不确定您说的setValue等是什么意思,需要您检索现有数据。插入新记录的基本流程如下:

private DatabaseReference mDatabase;
// get reference to your Firebase Database.
mDatabase = FirebaseDatabase.getInstance().getReference();
//and here you add a new child to your 'requests' collection
//I am assuming you have a Request model like this..
Request newRequest = new Request(some-params);
mDatabase.child("requests").child(someRequestId).setValue(newRequest);
您可以查看的基本使用指南

更新: 根据您的意见-我认为您希望做的事情可以通过以下方式实现: 您可以使用
push()

Firebase newRequestRef = mDatabase.child("request").push();
newRequestRef.setValue(newRequest);
这应该可以做到


我希望这能有所帮助。

Firebase官方博客上有一篇很好的老文章,解释了为什么我们应该避免在数据库中使用数组:

因此,在不替换阵列的情况下修改阵列是不可能的。我建议将您的数据库结构更改为

"requests" : {
    "<pushKey1>" : {
        "interests" : [ "x" ],
        "live" : true,
        "uIds" : {
            "<pushKey1>" : "user1",
            "<pushKey2>" : "user2"
        }
    },
    "<pushKey2>" : {
        "interests" : [ "y" ],
        "live" : true,
        "uIds" : {
            "<pushKey1>" : "user2"
        }
    }
}
如果您有问题,请在此处发表评论,希望这有帮助:)

建议您使用不同的数据结构:

"requests" : {
  "-KSVYZwUQPfyosiyRVdr" : {
    "interests" : { "x": true },
    "live" : true,
    "uIds" : { 
      "user1": true, 
      "user2": true 
    }
  },
  "-KSl1L60g0tW5voyv0VU" : {
    "interests" : { "y": true },
    "live" : true,
    "uIds" : { 
      "user2": true 
    }
  }
}
以下是此数据结构工作得更好的几个原因:

  • 每个uid现在只能自动显示一次。我们基本上将数据建模为一个集合,而不是使用数组
  • 现在添加一个项目就像
    ref.child(“uUids”).child(“user3”).setValue(true)
  • 现在可以检查安全规则中是否存在uid
我已经开始对自己进行重新迭代:每当你发现自己在做
array.contains(“xyz”)
,你可能应该使用集合而不是数组。上面带有
“key”:true的映射是在Firebase上设置的实现

效率 有些人可能认为数组是存储数据的一种更有效的方式,但在Firebase的情况下,情况并非如此:

你所看到的:

"uIds" : [ "user1", "user2" ]
Firebase存储的内容:

"uIds" : {
  "0": "user1",
  "1": "user2"
}
所以存储一个集合几乎是一样的:

"uIds" : { 
  "user1": true, 
  "user2": true 
}

在Frank van Puffelen answer上加上2美分,就可以使用push操作中的密钥作为请求的唯一标识符。另外,如果您使用哈希映射来更新子对象,那么您的DB将不会被覆盖

 // Create a node on Server and get key
  String requestID = AdminController.getInstance().referenceFromUrl
                        .child(END_POINT_REQUESTS)
                        .push().getKey();

  //use key as ID for your Object which you want to push as unique identifier of your model
  requestToPush.setRequestId(requestID );

 //Add updated Model Object in a Map to update DB instead of over writing
 requestsMap.put(requestID , requestToPush);

 //Update newly created DB nodes with data
   referenceFromUrl
            .child(END_POINT_REQUESTS)
            .updateChildren(productsMap,
                    new DatabaseReference.CompletionListener() {
                        @Override
                        public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {

                            if (databaseError != null) {
                                Log.e(TAG, "Error: Data could not be saved "
                                        + databaseError.getMessage());
                            } else {
                                Log.e(TAG, "Success : Data saved successfully.");
                            }
                        }
                    });
结果


你说我检索数据是什么意思?这都是关于更新的。请尝试进一步澄清这一点,以便更容易地帮助您。通过检索数据,我的意思是运行ValueEventListener来读取现有UID列表,但您不必附加侦听器来更新子项。你只需要一个推荐人。只有当你特别想读取数据时,你才会使用监听器。没错!这正是我在他的问题中困惑的地方。@Han,似乎您只想在插入请求之前先生成ID-在这种情况下,您只需使用
push
,它将返回
Ref
,然后使用此
Ref
setValue
到新请求。我已经在更新后的答案中添加了这一点。如果是web javascript,那么它将是ref.child(“uUids”).child(“user3”).set(true);我有点困惑。既然我们不喜欢数组,那么为什么会有反对“兴趣”的数组呢?
"uIds" : {
  "0": "user1",
  "1": "user2"
}
"uIds" : { 
  "user1": true, 
  "user2": true 
}
 // Create a node on Server and get key
  String requestID = AdminController.getInstance().referenceFromUrl
                        .child(END_POINT_REQUESTS)
                        .push().getKey();

  //use key as ID for your Object which you want to push as unique identifier of your model
  requestToPush.setRequestId(requestID );

 //Add updated Model Object in a Map to update DB instead of over writing
 requestsMap.put(requestID , requestToPush);

 //Update newly created DB nodes with data
   referenceFromUrl
            .child(END_POINT_REQUESTS)
            .updateChildren(productsMap,
                    new DatabaseReference.CompletionListener() {
                        @Override
                        public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {

                            if (databaseError != null) {
                                Log.e(TAG, "Error: Data could not be saved "
                                        + databaseError.getMessage());
                            } else {
                                Log.e(TAG, "Success : Data saved successfully.");
                            }
                        }
                    });