Rahul Mishra
Rahul Mishra

Reputation: 603

FireBase onDataChange() not working

This function is returning no data in spite of receiving snapshots and adding the data in ArrayList in onDataChange() function but in the end, it is returning ArrayList with size 0.

List<ProductEntity> feed_data() {
        final List<ProductEntity> feededProducts = new ArrayList<>();

    progressDialog = new ProgressDialog(this);
    progressDialog.setMessage("Please wait...");
    progressDialog.show();
    mDatabase = FirebaseDatabase.getInstance().getReference("/products");

    //adding an event listener to fetch values
    mDatabase.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot snapshot) {
            //dismissing the progress dialog
            progressDialog.dismiss();

            //iterating through all the values in database
            for (DataSnapshot postSnapshot : snapshot.getChildren()) {
                ProductEntity upload = postSnapshot.getValue(ProductEntity.class);
                Log.d("error", "onDataChange: " + upload.about);
                feededProducts.add(upload);
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.d("Error", "onCancelled: " + databaseError.getMessage());

            NestedScrollView root_layout = findViewById(R.id.category_root_layout) ;
            Snackbar.make(root_layout, "Internal Error!!", Snackbar.LENGTH_SHORT).show();
        }
    });
    return feededProducts ;
}

Upvotes: 0

Views: 7420

Answers (3)

Rahul Mishra
Rahul Mishra

Reputation: 603

I just needed to initialize and set the Adapter after adding all the data in my Arralist as pointed out above like this and it solved my problem:

mDatabase.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot snapshot) {

                for (DataSnapshot postSnapshot : snapshot.getChildren()) {
                    ProductEntity upload = postSnapshot.getValue(ProductEntity.class);
                    productList.add(upload);
                }

                productsRecyclerAdapter = new ProductsRecyclerAdapter(productList, CategoryActivity.this);
                products.setAdapter(productsRecyclerAdapter);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                NestedScrollView root_layout = findViewById(R.id.category_root_layout);
                Snackbar.make(root_layout, "Internal Error!!", Snackbar.LENGTH_SHORT).show();
            }
        });

Upvotes: 1

Lukas Gruber
Lukas Gruber

Reputation: 46

You'll need to create an interface which you will call when the data is received.

interface DataReceivedListener{
    void onDataReceived(List<ProductEntity> data);
}

void feed_data(DataReceivedListener listener) {
    final List<ProductEntity> feededProducts = new ArrayList<>();

    progressDialog = new ProgressDialog(this);
    progressDialog.setMessage("Please wait...");
    progressDialog.show();
    mDatabase = FirebaseDatabase.getInstance().getReference("/products");

    //adding an event listener to fetch values
    mDatabase.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot snapshot) {
            //dismissing the progress dialog
            progressDialog.dismiss();

            //iterating through all the values in database
            for (DataSnapshot postSnapshot : snapshot.getChildren()) {
                ProductEntity upload = 
                postSnapshot.getValue(ProductEntity.class);
                Log.d("error", "onDataChange: " + upload.about);
                feededProducts.add(upload);
            }

            listener.onDataReceived(feededProducts);

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.d("Error", "onCancelled: " + databaseError.getMessage());

            NestedScrollView root_layout = 
            findViewById(R.id.category_root_layout) ;
            Snackbar.make(root_layout, "Internal Error!!", 
            Snackbar.LENGTH_SHORT).show();
        }
    });
}

Either implement the DataReceivedListener interface in your Activty and override the 'onDataReceived()' function and pass 'this' to 'feed_data(DataReceivedListener listener)' or create a DataReceivedListener as a variable and pass that variable to 'feed_data(DataReceivedListener listener)'

When the data is received in 'onDataChange(DataSnapshot snapshot)' it calls the function of the interface and then your overridden function will be called or the one you initilazied the 'DataReceivedListener' variable with. Depends on how you did it.

Put your code where you need the data inside the 'onDataReceived(List data)' function.

Upvotes: 1

Ragesh Ramesh
Ragesh Ramesh

Reputation: 3520

onDataChange(DataSnapshot snapshot) is called asynchrounously. That is will be called when we get data back from Firebase.

Hence your return feededProducts is called before onDataChange(DataSnapshot snapshot) method, so you will be returning empty list everytime.

You will have to call notifydatasetchanged on your adapter inside onDataChange(DataSnapshot snapshot)

Upvotes: 3

Related Questions