Saya memiliki masalah dengan sinkronisasi pengambilan data database Firebase. Saya bisa mendapatkan data tetapi pengembalian berfungsi sebelum itu. Jadi data saya tidak pernah dimasukkan ke dalam daftar yang dimaksud.

Ini kode saya:

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;
}

Metode ini dipanggil dari kelas lain untuk mendapatkan daftar 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);
}

Kedua metode ini berada di kelas yang sama yang disebut BarcodeDecoderDataMatrix. Saya membuat turunan dari kelas ini dari kelas lain dan memanggil metode getDataMatrix. Saya mengharapkan untuk mendapatkan daftar termasuk nilai-nilai saya. Saya bisa mendapatkan nilai barcodeNum, expiredDate, serialNum, partyNum tanpa masalah. Tetapi daftar tersebut tidak termasuk nama obat, nama perusahaan, dan informasi harga. Saya membuat debug jadi saya tahu saya bisa mendapatkan data dari database. Saya bisa melihatnya di variabel medicineData. Saya cukup yakin ini adalah masalah sinkronisasi. Karena data saya di medicineData tetapi tidak bisa dimasukkan ke dalam daftar sebelum kembali dipanggil.

Bagaimana saya bisa mewujudkannya?

0
muratcanyeldan 10 Maret 2020, 19:22

1 menjawab

Jawaban Terbaik

addListenerForSingleValueEvent() metode yang Anda gunakan dalam kode Anda, tidak sinkron. Ini berarti bahwa metode tersebut segera kembali, sedangkan metode onDataChange() diaktifkan hanya jika hasilnya tersedia.

Apa yang Anda lakukan dalam kode Anda salah karena Anda berasumsi bahwa hasilnya segera tersedia dan tidak.

Saat Anda memanggil metode getMedicineName(), Anda harus langsung menggunakan dataMatrix dalam panggilan balik, setelah diketahui bahwa data tersedia.

Untuk informasi lebih lanjut, saya sarankan Anda melihat bagian terakhir dari jawaban saya dari posting di mana saya telah menjelaskan bagaimana hal itu dapat dilakukan menggunakan panggilan balik khusus. Anda juga dapat melihat video ini untuk pemahaman yang lebih baik.

0
Alex Mamo 10 Maret 2020, 16:50