从Firebase数据库获取数据时出现同步问题

时间:2020-03-10 16:22:23

标签: java android firebase firebase-realtime-database

我的Firebase数据库数据检索同步出现问题。我能够获取数据,但在此之前可以返回数据。因此,我的数据从未放入预期的列表中。

这是我的代码:

DatabaseManager databaseManager = new DatabaseManager();
MedicineData medicineData = new MedicineData();
boolean validated = false;
private static final String TAG = "BarcodeDecoderDataMatrix";

public Map getDataMatrix(String dataMatrixText) {

    Map<String, Object> dataMatrix = new HashMap<>();
    String barcodeNum = getBarcodeNumber(dataMatrixText);
    String expireDate = getExpireDate(dataMatrixText);
    String serialNum = getSerialNumber(dataMatrixText);
    String partyNum = getPartyNumber(dataMatrixText);

    dataMatrix.put("barcodeNumber",barcodeNum);
    dataMatrix.put("expireDate", expireDate);
    dataMatrix.put("serialNumber", serialNum);
    dataMatrix.put("partyNumber", partyNum);

    getMedicineName(barcodeNum, (success) -> {
        if(success){
            //find the data on database
            dataMatrix.put("medicineName", medicineData.getProductName());
            dataMatrix.put("companyName", medicineData.getCompanyName());
            dataMatrix.put("price", medicineData.getPrice());
        }
        else {
            //can't find on database
        }
    });

    return dataMatrix;
}

从另一个类调用此方法以获取dataMatrix列表。

    private void getMedicineName(String barcodeNum, SimpleCallback<Boolean> finishedCallback) {

      DatabaseReference rootRef = databaseManager.getReference();
      DatabaseReference medicinesRef = rootRef.child("MedicineList");
      Query queryMedicineNameFinder = medicinesRef.orderByKey().equalTo(barcodeNum);
      ValueEventListener valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for(DataSnapshot ds : dataSnapshot.getChildren()) {
                medicineData = ds.getValue(MedicineData.class);
            }

            if (medicineData != null){
                validated = true;
            }
            finishedCallback.run(validated);
        }
        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
            Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
            finishedCallback.run(false);
        }
    };
    queryMedicineNameFinder.addListenerForSingleValueEvent(valueEventListener);
}

这两个方法在称为BarcodeDecoderDataMatrix的同一类中。我从另一个类创建该类的实例,然后调用getDataMatrix方法。我希望得到一个包含我的价值观的清单。我可以毫无问题地获取BarcodeNum,expireDate,serialNum,partyNum值。但是该列表不包括medicineName,companyName和价格信息。我进行了调试,所以我知道我可以从数据库中获取数据。我可以在MedicineData变量中看到它。我很确定这是一个同步问题。因为我的数据在MedicineData中,但是在调用返回之前无法将其放在列表中。

我如何做到这一点?

1 个答案:

答案 0 :(得分:0)

您在代码中使用的

addListenerForSingleValueEvent()方法是异步的。这意味着它会立即返回,而onDataChange()方法仅在结果可用时才触发。

您在代码中执行的操作是错误的,因为您假设结果立即可用,而没有结果。

当调用getMedicineName()方法时,应在知道可用数据后直接在回调中使用dataMatrix

有关更多信息,建议您从此 post 中查看anwser的最后一部分,其中我已经解释了如何使用自定义回调来完成。您也可以查看此 video 以获得更好的理解。