Android:Firebase查询值中的单个字

问题描述 投票:1回答:2

我想在我的应用项目中使用Firebase实时数据库。我想检查用户填写的单词是否存在于数据库中。

这是我的数据库ss:

enter image description here

这是我的代码:

private Button button;
private FirebaseDatabase database;
private DatabaseReference mRef;
private TextView tvResult;
private EditText et1;

    et1=(EditText) findViewById(R.id.et1);
    button=(Button) findViewById(R.id.btn);
    tvResult=(TextView) findViewById(R.id.tvResult);
    database=FirebaseDatabase.getInstance();
    mRef=database.getReference();

  button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            city=et1.getText().toString();


            Query query = mRef.child("app").orderByChild("cities").equalTo(city);
            query.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    if (dataSnapshot.exists()) {
                        // dataSnapshot is the "issue" node with all children with id 0
                        String get= dataSnapshot.getValue().toString();
                        tvResult.setText(get);
                    }
                }

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

正如我所说,用户填写edittext,点击一个按钮后,如果有数据库,我想在textview中显示书面城市。

java android firebase firebase-realtime-database
2个回答
0
投票

不幸的是,Firebase实时数据库中没有查询,如下所示:

mRef.child("app").orderByChild("cities").contains(city)

但对于小型数据集,有一种解决方法可以帮助您解决这个问题,即通过查询数据库获取cities属性的所有值并使用contains()方法,如下所示:

String str1 = dataSnapshot.child("cities").getValue(String.class);
String str2 = "london";
boolean b = str1.toLowerCase().contains(str2.toLowerCase());

如果你试图打印b的值,你会发现它是true。但是上述示例仅适用于非常小的数据集,它不适用于大型数据集,这是因为下载整个对象以搜索客户端字段是不切实际的。在这种情况下,我建议使用像Algolia这样的第三方搜索服务。


1
投票

你在cities中拥有的是一组值:一组值,每个值都是唯一的,顺序无关紧要。所以它是具有多个值的单个属性。虽然NoSQL数据库都是关于数据非规范化的,但实际上这是我建议您对其进行标准化的情况之一。

在实时数据库中,您通常会将数学集建模为此JSON:

cities: {
  london: true,
  paris: true,
  milan: true,
  ny: true,
  istanbul: true
}

这种数据结构的优点是:

  1. 根据定义,每个城市都是独一无二的,因为按键在其位置必须是唯一的。即这里没有办法让london两次。
  2. 现在,每个城市都作为单独的属性存储,这意味着您可以单独查询它。

例如,如果你有一个说trips的列表,其中每个旅行可以有一个cities节点,并且你按照我展示的模型,你可以查询包含纽约的所有城市:

firebase.database().ref("cities").orderByChild("cities/ny").equalTo(true)

由于Firebase实时数据库索引的工作方式,这在技术上可行,但性能会非常糟糕。有关这方面的更多信息,以及如何对此进行建模以允许用例的解释,请查看我的答案:Firebase query if child of child contains a value

我绝对建议您检查Cloud Firestore。这个用例正是Firestore最近发布了一些重大改进的用例。在Firestore中,您现在可以将数据集存储在数组中:

["london", "paris", "milan", "ny", "istanbul"]

所以再说一遍,你有一个旅行集合,每次旅行你有一个字段cities,其值是上面的数组。您现在可以查询包含纽约的旅行:

firebase.firestore().collection("trips").where("cities", "array-contains", "ny")

与实时数据库不同,在Firestore上,此查询可以很好地扩展。有关这方面的更多信息,请参阅博客文章Better Arrays in Cloud Firestore!

© www.soinside.com 2019 - 2024. All rights reserved.