正在从数据库中获取数据,但仍给出NullPointerException

时间:2018-11-07 15:24:14

标签: android firebase google-maps firebase-realtime-database

我正在MapActivity上工作,我从数据库中获取供应商信息并将其存储在Supplier对象中。我正在调用两个函数fetchSupplier()FetchStationInfo(),其中第一个函数获取供应商信息并存储到Object中,第二个函数使用它。因此,问题是当我单独运行fetchSupplier()时,数据就被提取并存储在对象中,但是当我在FetchStationInfo()之后调用两个函数(即fetchSupplier())时,会在FetchStationInfo()。这是我调用函数的方式:

@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    fetchSupplier();
    fetchStationInfo();
}

我的两个功能:

private void fetchSupplier(){
    String uid = mAuth.getUid();
    mDatabase = FirebaseDatabase.getInstance().getReference()
            .child("SUPPLIERS").child(uid);

    mDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            supplier = dataSnapshot.getValue(Supplier.class);
            Log.i("USER FETCH COMPLETE ","["+supplier.getName()+"]");
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.i("FETCHING USER [ERROR] ",databaseError.getMessage());
        }
    });
}

private void fetchStationInfo(){
    //Exception is here in this line where I am calling `getStation_id()`
    mDatabase = FirebaseDatabase.getInstance().getReference()
            .child("STATIONS").child(supplier.getStation_id());

    mDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            station = dataSnapshot.getValue(Station.class);
            Log.i("STATION FETCH COMPLETE ","["+station.getName()+"]");
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.i("STATION FETCH [ERROR] ",databaseError.getMessage());
        }
    });
}

我的对象是全局声明的。已经工作了几个小时,但无法修复。我的firebase结构: enter image description here

1 个答案:

答案 0 :(得分:2)

问题是fetchStationInfo()试图从supplier获取fetchSupplier()

请记住,Firebase调用是异步的,您正试图在获取供应商的同时获取供应商。

所以,如果您这样做

public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    fetchSupplier();
    fetchStationInfo();
}

这两个方法将触发,并且由于它们是异步的,因此您不知道哪个方法先结束,因此,如果fetchStationInfo首先结束,则由于fetchSupplier尚未完成,suppliers的值为空。仍在获取结果。

为了解决此问题,您可以在fetchSuppliers()之后创建一个简单的界面,该界面会在作业完成后通知您何时完成该作业,在您运行fetchStationInfo()的该界面的回调中,按此顺序,您将始终具有供应商信息,然后再尝试在fetchStationInfo()中获取。

这就是Race Condition

请访问以下链接,以更好地了解其工作原理:

How to return dataSnapshot value as a result of a method?

android - Firebase return value from datasnapshot Why?