Android Firebase同步检索数据并“返回”数据

时间:2019-02-26 17:48:45

标签: java android firebase firebase-realtime-database

对不起,如果这看起来像是一个愚蠢的问题,但是我还没有找到类似的问题,所以在这里。

我有一个DatabaseService类,用于从Firebase实时数据库检索数据(动物)。从上一篇文章中我了解到,由于这些API调用是异步的,因此应该创建一个Interface以便同步数据检索(onDataChange()方法)

我的问题是:

  1. 为什么创建此接口并将其作为参数传递来同步数据检索?在我的代码中,为什么调用接口的onCallBack方法(直到后来才定义)才使它发生,为什么要执行该步骤?
  2. 已将该类创建为数据库服务(因此得名),我希望它为包含此服务的Activity MyAnimalsActivity返回动物列表(List),以创建RecyclerView。有什么办法可以将此Interface方法中的“ void”更改为“ List”以具有类似

    List<Animal> listAnimals = databaseService.readData(); 
    

    或者应该删除整个DatabaseService类,并 在MyAnimalsActivity本身中添加其代码,以便在onDataChange()方法的全局列表中添加Animals对象?

DatabaseService:

public class DatabaseService {

    private FirebaseDatabase firebaseDatabase;
    private DatabaseReference firebaseRootRef;
    private DatabaseReference animalsRef;
    List<Animal> animalsList;

    public DatabaseService() {

        this.firebaseDatabase = FirebaseDatabase.getInstance();
        this.firebaseRootRef = firebaseDatabase.getReference();
        this.animalsRef = firebaseDatabase.getReference("animals");

        animalsList = new ArrayList<>();
    }


    private interface FirebaseCallback {
        void onCallback(List<Animal> list);
    }

    public void readItemsFromDatabase(final FirebaseCallback firebaseCallback) {

        ValueEventListener valueEventListener = new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                animalsList.clear();

                //dataSnapshot.getChildren() ---> iterate through entire dataSnapshot Object, to get the items names
                for(DataSnapshot ds : dataSnapshot.getChildren()) {
                    Animal animal;
                    animal = ds.getValue(Animal.class);
                    animalsList.add(animal);
                }

                firebaseCallback.onCallback(animalsList);

            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                Log.d("DATABASE_TAG", databaseError.getMessage());
            }
        };

        animalsRef.addValueEventListener(valueEventListener);

    }


    public void readData() {
        readItemsFromDatabase(new FirebaseCallback() {
            @Override
            public void onCallback(List<Animal> list) {
                Log.d("DATABASE_TAG", list.toString());
            }
        });
    }

}

MyAnimalsActivity:

public class MyAnimalsActivity extends AppCompatActivity {

private RecyclerView recyclerView;
private RecyclerView.Adapter animalAdapter;

private List<Animal> listAnimals;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my_animals);

    DatabaseService databaseService = new DatabaseService();
    databaseService.readData();


    recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
    recyclerView.setHasFixedSize(true); //every item of the recyclerview has a fixed size;
    recyclerView.setLayoutManager(new LinearLayoutManager(this));

    listAnimals = new ArrayList<>();
    //listAnimals  =  databaseService.readData();  ??


}
}

1 个答案:

答案 0 :(得分:1)

编写一个返回可能不存在的异步值的方法,如果您在有数据之前调用它,可能会导致NullPointers。

为简单起见,由于方法readItemsFromDatabase是公共的,因此可以从MyAnimalsActivity调用它,并从那里获取数据。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my_animals);

    DatabaseService databaseService = new DatabaseService();
    databaseService.readItemsFromDatabase(new DatabaseService.FirebaseCallback() {
            @Override
            public void onCallback(List<Animal> list) {
                Log.d("DATABASE_TAG", list.toString());

            }
        });
...

我已经将您的问题与我的一个项目隔离开了,并且正在运行;另外,您可以检查可以为您解决所有这些问题的MVP模式,您的代码将变得更加干净。