Grumpy Cat
Grumpy Cat

Reputation: 1249

How to show loading message while fetching data from Firebase Database?

I'm using Firebase to display data into a textview. I use an asynctask to load data in the background, while loading, I want to show a loading message before the data loads into my textview.

But my loading data popup is not showing.(i.e doinBackground method finish it works immediately) and the user sees empty textviews and only after sometime that Firebase data loads.

How to prevent this and show process dialog until my textview get loaded with Firebase data?

here is my code
<pre>
<code>
public class LastPage extends AppCompatActivity {
    TextView title, author, article;
    DatabaseReference mDatabase;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_last_page);


        title = (TextView) findViewById(R.id.last_page_title);
        author = (TextView) findViewById(R.id.last_page_author);
        article = (TextView) findViewById(R.id.last_page_article);

        mDatabase = FirebaseDatabase.getInstance().getReference();

        new LoadFirebaseData().execute();


    }

    private class LoadFirebaseData extends AsyncTask<Void, Void, Integer>
    {
        private ProgressDialog Dialog = new ProgressDialog(LastPage.this);

        @Override
        protected void onPreExecute()
        {
            try {
                Dialog.setMessage("Doing something...");
                Dialog.show();
            }catch (Exception e)
            {
                e.printStackTrace();
            }

        }

        @Override
        protected void onPostExecute(Integer result)
        {

            if(result==0)
            {
                //do some thing
            }
            // after completed finished the progressbar
            Dialog.dismiss();
        }

        @Override
        protected Integer doInBackground(Void... params) {

            mDatabase.child("version_1_5").child("title").addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    String temp = dataSnapshot.getValue(String.class);
                    title.setText(temp);
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });

            mDatabase.child("version_1_5").child("author").addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    String temp = dataSnapshot.getValue(String.class);
                    author.setText(temp);
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });

            mDatabase.child("version_1_5").child("article").addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    String temp = dataSnapshot.getValue(String.class);
                    article.setText(temp);
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });

            return 0;
        }


    }
}


</code>
</pre>

JSON tree structure:

Root
    Version_1_5
        Title:TitleValue
        Author:AuthorValue
        Article:ArticleValue

Upvotes: 9

Views: 13359

Answers (3)

Christopher Nolan
Christopher Nolan

Reputation: 1107

As by default visibility of progressbar is true in layout file ,so we only need to set it to false. You only need do this line in your layout file as follows. Suppose this is the simplest progressbar initialization.

<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"/>

Here the main thing is android:visibility="invisible". Hope it helps many & save their time.

Upvotes: 0

Yugansh Tyagi
Yugansh Tyagi

Reputation: 656

I had the same problem when I was fetching data from firebase, so I logged the Code and saw that the problem is

The onPostExecute() code is run before the data from Firebase has been loaded to the app.

So I thought of an hack and instead of calling adapter.notifyDataSetChanged() on onPostExecute() I called it in the doInBackground() method after the data from Firebase has been loaded and also hid the progress bar in the same methond like this -

@Override
    protected void onPreExecute() {
        super.onPreExecute();
        progressBar.setIndeterminate(true);
        progressBar.setVisibility(View.VISIBLE);
    }

    @Override
    protected String doInBackground(String... params) {
        DataBaseReference = FirebaseDatabase.getInstance().getReference("child").child("something");
            DataBaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    for (DataSnapshot ds : dataSnapshot.getChildren()) {
                        //Code for Fetching data from firebase

                    }
                    categoryDetailsFragmentAdapter.notifyDataSetChanged();
                    progressBar.setVisibility(View.GONE);
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });
        }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        //progressBar.setVisibility(View.GONE);
        //categoryDetailsFragmentAdapter.notifyDataSetChanged();
    }

I hope this solves your problem.

Upvotes: 0

Jay Vignesh
Jay Vignesh

Reputation: 384

you should use addListenerForSingleValueEvent to fetch the data from the node once not for the every single node

private ProgressDialog Dialog = new ProgressDialog(LastPage.this);
Dialog.setMessage("Doing something...");
Dialog.show();
mDatabase.child("version_1_5").addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot Snapshot : dataSnapshot.getChildren()) {
            if(Snapshot.getKey().toString().equalsIgnoreCase("Title")){
                String temp = dataSnapshot.getValue(String.class);
                title.setText(temp);
            }
            else if(Snapshot.getKey().toString().equalsIgnoreCase("Author")){
                String temp = dataSnapshot.getValue(String.class);
                author.setText(temp);
            }
            else if(Snapshot.getKey().toString().equalsIgnoreCase("Article")){
                 String temp = dataSnapshot.getValue(String.class);
                article.setText(temp);
            }
        }
        Dialog.hide();
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
});

Upvotes: 6

Related Questions