从 firebase 数据库中获取多个值

Posted

技术标签:

【中文标题】从 firebase 数据库中获取多个值【英文标题】:Fetch multiple values from firebase database 【发布时间】:2018-10-03 15:36:02 【问题描述】:

在我们的数据库结构中,每个“用户”拥有多个投标 ID,每个投标 ID 代表“工作”数据库中的一个入口点。 目前,当我们想要遍历一个人的所有工作时,代码看起来类似于:

final DatabaseReference mDatabaseJobs = FirebaseDatabase.getInstance().getReference().child("Jobs");
        DatabaseReference mDatabaseUser = FirebaseDatabase.getInstance().getReference().child("Users").child(currentUser.getUid());
        mDatabaseUser.addListenerForSingleValueEvent(new ValueEventListener() 
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) 
                DataSnapshot userBids = dataSnapshot.child("listOfBids");
                final int num_user_bids = (int) userBids.getChildrenCount();

                for(final DataSnapshot job : userBids.getChildren())
                    String jobId = job.getValue(String.class);
                    mDatabaseJobs.child(jobId).addListenerForSingleValueEvent(new ValueEventListener() 
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) 
                            bid_count.addAndGet(1);

这是数据库结构,目标是获取特定人员的所有工作。

有没有办法一次检索所有作业?也许是键列表?而不是为每个调用添加侦听器? 如果不是,我知道 firebase 异步获取数据,但它是并行执行的吗? 即我们目前增加一个原子整数以了解 firebase 是否已经获取所有作业,因为我们不希望线程同时增加计数器,在我们当前的实现中是否有必要? 谢谢!

【问题讨论】:

请添加您的数据库结构并指明您想要获取的确切数据。 【参考方案1】:

您可以在“用户”之外保留一个 HashMap,用当前用户的作业列表填充它。然后将另一个侦听器附加到“作业”并遍历您的 hashMap 并获取您想要的特定作业。下面是参考代码:

HashMap<Integer, String> listOfJobs = new HashMap<>();
DatabaseReference mDatabaseUser = FirebaseDatabase.getInstance().getReference().child("Users").child(currentUser.getUid()).child("listOfBids");

mDatabaseUser.addListenerForSingleValueEvent(new ValueEventListener() 
@Override
public void onDataChange(DataSnapshot dataSnapshot) 
    if (dataSnapshot.exists) 
        listOfJobs.putAll((Map) dataSnapshot.getValue());
    
    // Here you can add a listener to the entire "Jobs" reference like this
    DatabaseReference mDatabaseJobs = FirebaseDatabase.getInstance().getReference().child("Jobs");
    mDatabaseJobs.addListenerForSingleValueEvent(new ValueEventListener() 
        @Override
        public void onDataChange(DataSnapshot userDataSnapshot) 
            if (userDataSnapshot.exists) 
                for (String jobId : listOfJobs.values()) 
                    if (userDataSnapshot.hasChild(jobId) 
                        DataSnapshot job = userSnapshot.child(jobId);
                        // here you can use job snapshot
                        bid_count.addAndGet(1); // something like this?
                    
                
            
        

);

基本上,您正在向未嵌套或不深的事物添加侦听器,并使用循环来获取子项,而不是向嵌套的子项添加侦听器。

希望这会有所帮助。

【讨论】:

您不是为了单个用户查询而获取整个作业数据库吗?听起来很贵,不是吗? 我觉得不贵。 Firebase 是一个基于 NoSQL 的实时数据库。它足够强大,可以处理您正在尝试做的事情。您不能编写查询并提取数据库的一部分。如果你愿意,你可以尝试重构你的数据库。 如果我错了,请纠正我,但是无论 firebase 的效率如何,mDatabaseUser.addListenerForSingleValueEvent 行都会将整个作业数据库提取到客户端电话 @DsCpp 是的,它在本地提取所有数据,我认为它并不昂贵。如果您在“职位”中的数据过多,您可以通过添加.limitToFirst(1000).limitToLast(500)来拉取限额

以上是关于从 firebase 数据库中获取多个值的主要内容,如果未能解决你的问题,请参考以下文章

如何从 OnMarkerClickListener 内的 Firebase 数据库中获取特定值?

如何使用 Stream Builder 从多个 firebase 集合中获取数据

从多个子集合中获取文档 - Firebase [重复]

是否可以从 Firebase 获取可以映射到 Java 中多个子类的数据?

如何使用java从firebase数据库中的列表中获取所有值?

无法使用 Swift 5 (iOS) 从 Firebase 数据库中获取和打印单个值