代码之家  ›  专栏  ›  技术社区  ›  Mido2009

Firebase Android,检查是否存在对象(具有多个子对象)

  •  1
  • Mido2009  · 技术社区  · 8 年前

    我使用Firebase数据库来存储用户报告。每个用户只能提交10份不同的报告。

    Image

    我的问题是,如何检查用户是否已经提交了特定报告?

    我必须检查“位置”、“模式”、“spinnerOne”的值,并将它们与用户刚刚输入的内容进行比较,如果已经存在,则不添加到数据库中,如果已经存在,则添加到数据库中。以下是我的尝试:

    public void checkifentryExistofNot() {
                    uniqueID = mDatabaseReference.push().getKey();
                    fullname = “Jasna Kuljancic”;
                    CATEGORY = “Clinical First”); 
    
                    final Report subreport = new Report(SELECTED_LOCATION,
                            locationEditText.getText().toString(),
                            modeEditText.getText().toString(),
                            Integer.parseInt(dateEditText.getText().toString()));
    
                    mDatabaseReference.child("Students Reports").child(fullname).child(CATAGORY).addListenerForSingleValueEvent(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {
                    int numberofCount = (int) dataSnapshot.getChildrenCount();
                    if (numberofCount == 0) {
    
                        mDatabaseReference.child("Students Reports").child(fullname).child(CATAGORY).child(uniqueID).setValue(subreport);
    
                    }
    
                    if (numberofCount != 0) {
    
                        for (DataSnapshot child : dataSnapshot.getChildren()) {
                            Report datareports = child.getValue(Report.class);
                            thelocation = datareports.getLocation();
                            themode = datareports.getMode();
    
                            if (thelocation.equals(locationEditText.getText().toString()) && themode.equals(modeEditText.getText().toString())) {
                                break;
                            } else {
                                mDatabaseReference.child("Students Reports").child(fullname).child(CATAGORY).child(uniqueID).setValue(subreport);
                            }
                        }
                    }
                }
    
                @Override
                public void onCancelled(DatabaseError databaseError) {
                }
            });
        }
    

    我的解决方案的问题是,for循环将检查每个报告,在每种情况下,它要么添加一个新报告,要么不添加,但这将发生在现有报告的数量上,它应该只执行一次。

    换句话说,如果我们有3个条目,并且每次都不存在,那么它将提交3次报告(这不是很糟糕)。但是如果它检查第一个报告并且它确实存在,循环将退出,因为我在那里有一个中断(这很好),但是假设第二个报告将是一个重复的报告,它将已经将其添加到数据库中,因为第一个条目不是重复的。

    我觉得我做得太多了,应该有一个更快的方法来做到这一点。

    3 回复  |  直到 7 年前
        1
  •  2
  •   Alex Mamo    8 年前

    Firebase查询只能按单个属性排序/过滤。所以没有 WHERE location_mode_spinnerOne

    Firebase-root
       |
       -- Students Reports
             |
             -- Jasna Kuljancic
                   |
                   -- Clinical First
                         |
                         -- -KuVRQ4OjdfKXCNdLWzb
                                |
                                --- data: 3939393
                                |
                                --- location: "fifififi"
                                |
                                --- mode: "ododododo"
                                |
                                --- spinnerOne: "Asylum Hill Family Clinic"
                                |
                                --- location_mode_spinnerOne: "fifififi_ododododo_Asylum Hill Family Clinic"
    

    正如您可能看到的,我添加了新的复合值 location\u mode\u喷丝头 对于每个特定类别。这意味着您可以根据这个新的 location\u mode\u喷丝头

    DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
    DatabaseReference categoryRef = rootRef.child("Students Reports").child(fullname).child(CATAGORY);
    ValueEventListener eventListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            String searchedText = "fifififi";
    
            for(DataSnapshot ds : dataSnapshot.getChildren()) {
                String location_mode_spinnerOne = ds.child("location_mode_spinnerOne").getValue(String.class);
                if(!location_mode_spinnerOne.contains(searchedText)) {
                    categoryRef.child(uniqueID).setValue(subreport);
                }
            }
        }
    
        @Override
        public void onCancelled(DatabaseError databaseError) {}
    };
    categoryRef.addListenerForSingleValueEvent(eventListener);
    

    我给了你一个搜索的例子 fifififi 关键字。这个 searchedText 文本将是用户键入的精确搜索文本。

    tutorial

        2
  •  1
  •   Atif AbbAsi    8 年前

    你所要做的就是让一个模型类将你的值保存在对象中,在编辑时检查对象是否有相同的数据,然后不更新数据,如果有不同的数据,则更新数据。!

        3
  •  1
  •   mark42inbound    8 年前

    解决这个问题有两种方法。我认为对于第一种方法,您已经很清楚如何做到这一点。唯一遗漏的是将以下连续操作分开:[a]验证报告的唯一性和[b]将对象添加到数据库。可能有一个按钮用于添加报告。我建议,按下按钮获取所需表的数据快照。由于报告的唯一性仅限于单个用户,因此请为单个用户获取所有报告。然后简单地将目标报告与获取的报告进行比较,并进行相应的处理。如果唯一,则添加或报告副本。不同之处(你的代码)是不会附加任何事件侦听器。我认为您的代码处理与Firebase数据内联。在这里,您将获得数据转储,比较它,然后更新它。

    另一种方法是利用Firebase提供的规则。基本上,它与第一种方法相同,但所有工作都由firebase完成。以下是仅将唯一用户名插入Firebase的代码:

     "usernames": {
      "$usernameid": {
      ".read": "auth != null",
        ".write": "auth != null  && (!data.exists() || !newData.exists())"
      }
     }
    

    推荐文章