0

I have an activity where there are multiple recyclerViews where I populate them with data from my firestore database.

The code below is used to read the data from firestore and add it into the recyclerView (I also check there if users reported the items to remove them but it is not important for the question).

private void ShowNew(Boolean isGBS) {
    db.collection( "Items" ).orderBy( "DateCreated", Query.Direction.DESCENDING ).limit( AppConstants.Item_TO_LOAD ).get()
            .addOnSuccessListener( queryDocumentSnapshots -> {

                List<DiscoverItems> Items = new ArrayList<>();

                for (QueryDocumentSnapshot document : queryDocumentSnapshots) {
                    reportsNew = new ArrayList<>();
                    if (document.get( "Reports" ) != null) {
                        reportsNew = (List<String>) document.get( "Reports" );
                        if (reportsNew.size() > AppConstants.ALLOWED_REPORTS) {
                            PopUps popUps = new PopUps();
                            popUps.deleteReported( document.getString( "ItemID" ) );
                        } else {
                            Items.add( new DiscoverItems( document.getString( "ItemID" ) ) );
                        }
                    } else {
                        Items.add( new DiscoverItems( document.getString( "ItemID" ) ) );
                    }

                }

                List<DiscoverItems> finalItems = new ArrayList<>();
                List<String> ItemsID = new ArrayList<>();

                for (int i = 0; i < Items.size(); i++) {
                    finalItems.add( new DiscoverItems( Items.get( i ).getItemID() ) );
                    ItemsID.add(Items.get( I ).getItemID() );
                }

                saveToDB(ItemsID);

                discoverItemAdapter = new DiscoverItemAdapter( finalItems, listener );
                rv_NewItems.getItemAnimator().setChangeDuration( 0 );
                rv_NewItems.setAdapter( discoverItemAdapter );

            } );

}

Now, I had like to save the list of ItemsID into a room database in order to use it later for loading the recycerlView to save calls from kfirestore.

In order to do so, I wrote this code:

private void saveToDB(List<String> s) {
    class saveToDB extends AsyncTask<Void, Void, Void> {
        public saveToDB(List<String> s) {
            super();

        }
        @Override
        protected Void doInBackground(Void... voids) {

            //creating a task
            ItemId itemId = new ItemId();
            String itemsList = ItemId.ListToString( s );
            itemId.setItemId( itemsList );

            //adding to database
            ItemIdClient.getInstance( getApplicationContext() ).getItemDB()
                    .itemIdDao()
                    .insert( itemId );
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute( aVoid );
            Toast.makeText( getApplicationContext(), "Saved", Toast.LENGTH_LONG ).show();
        }
    }

    saveToDB s2db = new saveToDB(s);
    s2db.execute();
}

Now, my problem is that where it calls saveToDB it calls on an empty List. From my understanding, it is because firestore is an async task.

I tested the code of saveToDB() by saving a list that was created within the method and it works good so the problem is that it does not get any list to save when it is written as above.

How can I call saveToDB() so it will obtain the ItemsID list full with items and not an empty list?

From my understanding, it means to call saveToDB after firestore has finished its task but I don't know how to implement it.

Thank you

Ben
  • 1,737
  • 2
  • 30
  • 61
  • Hi Ben. Any code that needs data from Firestore, needs to be inside the onSuccess() method, or be called from there. Besides that, The Firestoree client already runs all network operations in a background thread. This means that all operations take place without blocking your main thread. Putting it in an AsyncTask does not give any additional benefits. Indeed, the Firebase API is asynchronous, so please check my answer from this **[post](https://stackoverflow.com/questions/48499310/how-to-return-a-documentsnapshot-as-a-result-of-a-method/48500679#48500679)**. – Alex Mamo Jan 10 '21 at 03:41
  • @AlexMamo, thank you for the answer. Correct me if im erong but thats what I did. I put saveToDB() inside the onSuccess of firebase. The problem I faced is that it seems like it started saveToDB before I had results from firestore which resulted in saving empty lists. It didnt block my thread. – Ben Jan 10 '21 at 05:55
  • Yes, and this is because of the asynchronous Firebase API. – Alex Mamo Jan 10 '21 at 05:57

0 Answers0