Firebase在单个RecyclerView中显示来自多个引用的数据

时间:2018-11-30 06:47:56

标签: java android performance firebase firebase-realtime-database

我有2个参考点。服务和服务类型。现在,您可以看到servicetype对于每个服务都有一个外键。 见下图: Here

现在,我想在两个方面都设置值侦听器,并读取数据并将其显示在RecyclerView中。每个服务都有多种服务类型。

我已经这样做了

    database = FirebaseDatabase.getInstance();
    myRef = database.getReference(getString(R.string.services));
    Query userQuery=myRef.child(FireBaseUtils.getFirebaseId());
    userQuery.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            ArrayList<Map<String,String>> temp=new ArrayList<>();

     for(DataSnapshot d: dataSnapshot.getChildren())
     {

      final Service  s=d.getValue(Service.class);
       String id=d.getKey();
         Log.d("TEST", ": "+id);

         serviceTypesReference=database.getReference(getString(R.string.servicetypes)).child(id);
         serviceTypesReference.addListenerForSingleValueEvent(new ValueEventListener() {

             @Override
             public void onDataChange(DataSnapshot dataSnapshot) {
                //services.clear();
                 ArrayList<ServiceType> serviceTypes=new ArrayList<>();
                 Service tempService=new Service(s.getName());
                 for(DataSnapshot dd:dataSnapshot.getChildren())
                 {
                     ServiceType st= dd.getValue(ServiceType.class);
                     Log.d("TEST", "typename: "+st.getName());
                     serviceTypes.add(st);
                 }
                 tempService.setServiceTypeArrayList(serviceTypes);

                 services.add(tempService);
                 serviceAdapter=new ServiceAdapter(services);
                 servicesRecyclerView.setAdapter(serviceAdapter);
             }

             @Override
             public void onCancelled(DatabaseError databaseError) {

             }
         });

             }            }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {

    }
});

在这里,服务对象包含一个名称和一个ArrayList,其中包含它包含的所有服务类型。 这些服务对象的列表将传递到RecyclerView的适配器。

现在,这可以完成工作,但是效率很低,并且可能会导致我现在看不到的错误。 有更好的方法吗?

谢谢。

1 个答案:

答案 0 :(得分:0)

  

我要显示所有服务以及其中的服务类型数量

要解决此问题,您应该查询数据库两次。假设getString(R.string.services)返回servicegetString(R.string.servicetypes)返回servicetypes,并且FireBaseUtils.getFirebaseId()拥有ID kPBgLQo9WrbhJ01eReOOWbox1Uy1,请执行以下代码:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference ref = rootRef.child("services").child("kPBgLQo9WrbhJ01eReOOWbox1Uy1");
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String key = ds.getKey();
            String name = ds.child("name").getValue(String.class);

            DatabaseReference keyRef = rootRef.child("servicetypes").child(key);
            ValueEventListener eventListener = new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    long count = dataSnapshot.getChildrenCount();
                    Log.d(TAG, name + "(" + count + ")");
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {
                    Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
                }
            };
            keyRef.addListenerForSingleValueEvent(eventListener);
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
    }
};
ref.addListenerForSingleValueEvent(valueEventListener);

我已经硬编码了节点的名称,以便更清楚地看到它。您的logcat中的结果将是:

Tiffin(3)
Milk(x)
//And so on