1

I'm developing an app in Android Studio and am using Firebase to store/retrieve data. This works fine, but when I save the retrieved data to a local variable and then attempt to display the data in a listview it doesn't work until I refresh the view.

This is my OnCreate function:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.my_chores);

    //get database reference and user data
    mDatabase = FirebaseDatabase.getInstance().getReferenceFromUrl("https://...");
    user = (User) getIntent().getSerializableExtra("user");

    configureBackButton();
    updateFromFirebase();
    display();
}

This is the update function (variable map is a global var):

private void updateFromFirebase() {
    final ArrayList<String> list;
    final String name = user.getName().toLowerCase();

    mDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot snapshot) {
            for(DataSnapshot child : snapshot.getChildren()) {
                ArrayList<String> list;
                String name;
                name = child.getKey();
                list = (ArrayList)child.getValue();
                map.put(name.toLowerCase(), list);
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            ...
        }
    });
    list = map.get(name);
    if(list==null) return;

    final ListView list_xml = (ListView) findViewById(R.id.list);
    final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list);
    list_xml.setAdapter(adapter);
}

And this is the display function:

private void display() {
    final ArrayList<String> list;
    final String name = user.getName().toLowerCase();

    list = map.get(name);
    if(list==null) return;

    final ListView list_xml = (ListView) findViewById(R.id.list);
    final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list);
    list_xml.setAdapter(adapter);

    list_xml.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            String item = adapter.getItem(position);
            list.remove(item);
            map.put(name, list);

            CoordinatorLayout coordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinatorLayout);

            Snackbar sb = Snackbar.make(coordinatorLayout, "Item Removed!", Snackbar.LENGTH_SHORT);
            sb.show();

            adapter.notifyDataSetChanged();
        }
    });

    }

Any insights to why it doesn't display the first time would be appreciated.

2
  • After the onDataChange, you will have every element you need from the firebase right? so try to set the adapter to your view there and it should work. Commented Apr 23, 2017 at 22:35
  • I tried to add my adapter code right after the onDataChange() but still within the addListenerForSingleValueEvent() and I kept getting errors saying it couldn't resolve constructor for the adapter, or it couldn't resolve a variable, and when I put the same block of code outside of addListenerForSingleValueEvent() but still within updateFromFirebase() (see updated post) no errors, but I get the same result as before - data appears only after I have already opened the view for a second time. Commented Apr 23, 2017 at 23:28

1 Answer 1

3

Since valueEventListener is an asynchronous function, it may not get the result right away, so I think it will be better if you update the UI, when the data is changed (onDataChange)

    @Override
    public void onDataChange(DataSnapshot snapshot) {
        for(DataSnapshot child : snapshot.getChildren()) {
            ArrayList<String> list;
            String name;
            name = child.getKey();
            list = (ArrayList)child.getValue();
            map.put(name.toLowerCase(), list);
        }
        //this is displaying result whenever change occurs
        display();
    }
Sign up to request clarification or add additional context in comments.

1 Comment

Yes that has solved it, I did not know of the asynchronicity of that function, thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.