首页 > 解决方案 > Firebase 实时数据排序(数字)

问题描述

我想在 Firebase Realtime 中将数据排序为 1-2-3-4-5。如果删除了第 3 个数据,我需要将新数据添加为 3。在 mysql 中很容易做到这一点,但我很难在 firebase 中找到它的方法。使用下面的代码,我计算数据并执行此过程,但是它下载太多并且成本很高。

有没有更便宜的方法来做到这一点?

使用此代码,我计算要添加的数字。然后我将它传递给控制整数。

private void setNextKontrol(){
    kontrolLst = removeDuplicates(kontrolLst);
    Collections.sort(kontrolLst);

    kontrol = 1;

    for(int index=0;index<kontrolLst.size();index++){
        if(kontrolLst.get(index)!=index+1){
            kontrol=index+1;

            return;
        }
    }
    kontrol=kontrolLst.size()+1;
}

public static <T> ArrayList<T> removeDuplicates(ArrayList<T> list)
{
    ArrayList<T> newList = new ArrayList<T>();

    for (T element : list) {

        if (!newList.contains(element)) {

            newList.add(element);
        }
    }

    return newList;
}

在这里,我正在下载所有 controldata 数据。

mDatabaseReference.child("/controldata/").addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot snapshot) {
            if (snapshot.exists()) {
                for (DataSnapshot snap : snapshot.getChildren()) {
                    b ne = snap.getValue(b.class);
                    kontrolLst.add(ne.kontrol);

                }
            }

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });
            
                

插入数据时,我将其作为 kontrol:1 插入到 controldata 中。

mDatabaseReference.child("/controldata/").child(key).child("kontrol").setValue(kontrol);

结尾

class b{
    public Integer kontrol;
    public String id;
    public void setIds(String id){
        this.id = id;
    }
    public b(){}
}

标签: javaandroidfirebasefirebase-realtime-database

解决方案


如果要将新数据插入现有列表中的第一个开放槽,则必须读取该列表(就像您现在所做的那样),或者对列表中第一个开放槽的位置有一些外部知识.


后一种方法意味着您在某个位置(在数据库中)保留一个额外的数据结构,您可以在其中跟踪打开的插槽。因此,每次从列表中删除项目时,都会将该索引添加到打开的插槽列表中:

openSlotIndexes: {
  "-Masdhdahk": 3,
  "-Mcasd78e1": 5
}

或者更简单,但您必须在它前面加上一个字符串,以防止 Firebase 将其解释为数组:

openSlotIndexes: {
  "slot3": true,
  "slot6": true
}

然后,当您需要找到一个开放的插槽时,您从开放插槽列表中读取第一项,写入控制列表中的该插槽,然后从开放插槽列表中删除该插槽。


另一种选择是在删除项目时不要从控制列表中完全删除它们,而是在其中放置一个标记值,以便您可以查询。例如,假设您使用“DELETED”作为标记值,​​您可以使用以下命令查询第一个已删除的项目:

kontrolRef.orderByValue().equalTo("DELETED").limitToFirst(1)

推荐阅读