如何使用两个子值在 Firebase 中进行搜索?

Posted

技术标签:

【中文标题】如何使用两个子值在 Firebase 中进行搜索?【英文标题】:How can I search in Firebase using two child values? 【发布时间】:2020-10-24 20:40:42 【问题描述】:

我想从 Firebase 实时数据库中获取搜索结果与子值匹配的所有节点。例如,考虑我的以下 Firebase 结构:

    -Users
        -uid
            -uname:abc
            -usurname:xyz
        -uid
            -uname:abc
            -usurname:pqr
        -uid
            -uname:hij
            -usurname:xyz

我的搜索关键字是abc xyz。我想从 -uname 和 -usurname 中获取结果,以向用户显示来自 Firebase 的匹配结果。

我的代码:

Query query = FirebaseDatabase.getInstance().getReference("Users").orderByChild("uname").startAt(getInput).orderByChild("usurname").startAt(getInput);
        query.addListenerForSingleValueEvent(new ValueEventListener() 
            public void onDataChange(@NonNull DataSnapshot snapshot) 
                Log.e("app","found: "+snapshot.getValue());
            
            public void onCancelled(@NonNull DatabaseError error) 

            
        );

错误:

    java.lang.IllegalArgumentException: You can't combine multiple orderBy calls!
            at com.google.firebase.database.Query.validateNoOrderByCall(Query.java:134)
            at com.google.firebase.database.Query.orderByChild(Query.java:609)

如何在 Java 代码中为此编写查询?

【问题讨论】:

【参考方案1】:

你可以这样做。我假设您已将搜索键分成两个字符串,即 searchKey1 和 searchKey2,如下所示。

    String searchKey="abc xyz";
    String[] str=searchKey.split(" ");
    String searchKey1=str[0];
    String searchKey2=str[1];

    // OR YOU CAN SPLIT HOWEVER YOU WANT //
    

databaseReference.child("users").addListenerForSingleValueEvent(new ValueEventListener() 
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) 
            for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) 
                if(dataSnapshot1.child("uname").exists()&&dataSnapshot1.child("usurname").exists()) 
                    if(dataSnapshot1.child("uname").getValue().toString().equals(searchKey1)&&dataSnapshot1.child("usurname").getValue().toString().equals(searchKey2)) 
                        //Do What You Want To Do.
                    
                
            
        

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) 

        
    );

【讨论】:

那是精确搜索。是否返回多个匹配的结果? 是的,它将返回多个搜索,即如果 uname 和 usurname 在列表中多次匹配,则 if 条件将运行多次。如果在 if 块的最后一行添加 break,那么它将只运行第一次。 好。如何限制前 50 个结果,然后在滚动时再获得下一个 50 个结果? 在 if 块中,将所有 DataSnaphots 存储在一个 ArrayList 中,然后一次获取 50 个,然后存储索引,然后在每次滚动时将其递增 50。【参考方案2】:

您必须创建另一个名为uname_usuername 的属性,它将包含两个值,然后您可以这样做:

DatabaseReference reference = FirebaseDatabase.getInstance().getReference();

Query query = reference.child("users").orderByChild("uname_usuername").equalTo("abc_xyz");
query.addListenerForSingleValueEvent(new ValueEventListener() 
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) 
        if (dataSnapshot.exists()) 
            for (DataSnapshot ds : dataSnapshot.getChildren()) 
                // do something with the data
            
        
    

    @Override
    public void onCancelled(DatabaseError databaseError) 
       throw databaseError.toException();
    
);

【讨论】:

以上是关于如何使用两个子值在 Firebase 中进行搜索?的主要内容,如果未能解决你的问题,请参考以下文章

如何获取内部子值 Firebase?

如何读取 Firebase 子值?

如何从 firebase 实时数据库中获取子值?

Firebase 和 Swift 如何按子值提取特定记录?

如何在firebase自动生成的密钥下编辑子值

如何使用 Cloud Functions for Firebase 获取子值的键?