0

UPDATE: I've decided to redit the question for better clarification and with more focused code.

The problem I am having is that I have an ArrayList of UserList objects which are the selected users from a previous activity, we'll call this selectedUsers. I have another object I would like to group the selectedUsers as well as the current user from Firebase into. This will be called mGroupMembers which holds GroupMember objects.

I am able to get the selectedUsers into the ArrayList of mGroupMembers, but I am not able to get the current user (referenced by their ID) into said ArrayList. I think the problem lies with Firebase. I'm not sure why when I call addListenerForSingleValueEvent, the current user's data does not add to the mGroupMembers ArrayList?

Here is my code:

public class TestActivity extends AppCompatActivity {

    //Tag
    private static String TAG = "TestActivity";

    private List<UserList> selectedUsers;
    private TextView mPickedText;
    private TextView mCurrentText;
    private TextView mMembCountText;
    private List<GroupMembers> mGroupMembers;
    private String memberNames;

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

        //Selected users from previous activity.
        selectedUsers = (List<UserList>) getIntent().getSerializableExtra("users");

        //Text Views
        mPickedText = (TextView) findViewById(R.id.first_text);
        mCurrentText = (TextView) findViewById(R.id.second_text);
        mMembCountText = (TextView) findViewById(R.id.third_text);

        //GroupMembs
        mGroupMembers = new ArrayList<>();

        //Current user.
        final String currentUserID = FirebaseAuth.getInstance().getCurrentUser().getUid();
        DatabaseReference mRef = FirebaseDatabase.getInstance().getReference().child("users").child(currentUserID);
        mRef.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                UserList user = dataSnapshot.getValue(UserList.class);
                GroupMembers member;

                //If the current user...
                if (Objects.equals(user.getUid(), currentUserID)) {
                    mCurrentText.setText("Current: " + user.getName());
                    member = new GroupMembers(user.getName(), user.getUsername(), user.getEmail(), user.getUid());

                    Log.d(TAG, "Member object contains...Name: " + user.getName() + "\n" +
                            "Username: " + user.getUsername() + "\n" +
                            "Email: " + user.getEmail() +
                            "uid: " + user.getUid());

                    selectedUsers.add(user);

                    mGroupMembers.add(member);

                    for (GroupMembers members : mGroupMembers) {
                        Log.d(TAG, "Member object contains...Name: " + members.getName() + "\n" +
                                "Username: " + members.getUsername() + "\n" +
                                "Email: " + members.getEmail() +
                                "uid: " + members.getUid());
                    }
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

        //Picked user.
        for (UserList selected : selectedUsers) {
            GroupMembers member = new GroupMembers();

            member.setName(selected.getName());
            member.setUsername(selected.getUsername());
            member.setEmail(selected.getEmail());
            member.setUid(selected.getUid());

            mGroupMembers.add(member);

            mPickedText.setText("Selected: " + selected.getName());
        }

        for (GroupMembers members : mGroupMembers) {
            memberNames = members.getName();
        }



        mMembCountText.setText("Group Members: " + mGroupMembers.size() + " ");
    }
}

And here is the Firebase Database

{
  "users" : {
    "S3l3yRh8TqRYNeTWQ7tKEdUe2K03" : {
      "email" : "antwon@domain.com",
      "name" : "Antwon ",
      "profilePicture" : " ",
      "uid" : "S3l3yRh8TqRYNeTWQ7tKEdUe2K03",
      "username" : "ant01"
    },
    "af7KgxP7QgZT3d6adtgwBRwnsaI2" : {
      "email" : "bill@domain.com",
      "name" : "Bill",
      "profilePicture" : " ",
      "uid" : "af7KgxP7QgZT3d6adtgwBRwnsaI2",
      "username" : "Bill123"
    }
  }
}

Here's what happens when I log the mGroupMembers ArrayList:

D/TestActivity: Member object contains...Name: Antwon 
                Username: ant01
                Email: antwon@domain.comuid: S3l3yRh8TqRYNeTWQ7tKEdUe2K03
D/TestActivity: Member object contains...Name: Bill
                Username: Bill123
                Email: bill@domain.comuid: af7KgxP7QgZT3d6adtgwBRwnsaI2
D/TestActivity: Member object contains...Name: Antwon 
                Username: ant01
                Email: antwon@domain.comuid: S3l3yRh8TqRYNeTWQ7tKEdUe2K03

The current user (Antwon) is being added, but why does it not display when I run the program? Right now the program simply displays the selected user's name as well as the current user's. Then it displays the size of mGroupMembers. The size, of course, is only 1 when it should be two.

Andrew Magana
  • 64
  • 2
  • 9
  • 2
    You've included link to a picture of the JSON tree in your question. Please replace that with the actual JSON as text, which you can easily get by clicking the Export JSON link in [your Firebase Database console](https://console.firebase.google.com/project/_/database/data/). Having the JSON as text makes it searchable, allows us to easily use it to test with your actual data and use it in our answer and in general is just a Good Thing to do. – Frank van Puffelen Jan 08 '17 at 21:28
  • Thank you for letting me know of this, I've edied it now @FrankvanPuffelen – Andrew Magana Jan 09 '17 at 03:00
  • Your problem description is not consistent with the code you posted. You say: _I've decided to try debugging `selectedUsers.add(mCurrentUsers)`_. That statement is not in the posted code. – Bob Snyder Jan 09 '17 at 06:07
  • 1
    Try initializing newRef and currentUserId on the onCreate method right before you add the listener – Rosário Pereira Fernandes Jan 09 '17 at 10:15
  • I tried this, and no luck @RosárioPereiraFernandes – Andrew Magana Jan 09 '17 at 16:30
  • Check my edit now, this should help clarify what I am trying to do. @qbix – Andrew Magana Jan 09 '17 at 16:41

1 Answers1

1

The unexpected behavior is the result of the asynchronous nature of Firebase listeners. onDataChange() does not execute until the data snapshot is retrieved from the Firebase servers. This typically takes a few milliseconds and will occur AFTER the statements following the addition of the listener. In the case of your code, this for-statement executes before onDataChange() has fired and added the current user:

    //Picked user.
    for (UserList selected : selectedUsers) {
        GroupMembers member = new GroupMembers();

        member.setName(selected.getName());
        member.setUsername(selected.getUsername());
        member.setEmail(selected.getEmail());
        member.setUid(selected.getUid());

        mGroupMembers.add(member);

        mPickedText.setText("Selected: " + selected.getName());
    }

Further explanation of Firebase's asynchronous loading of data is provided in this answer.

Community
  • 1
  • 1
Bob Snyder
  • 37,759
  • 6
  • 111
  • 158
  • So should I add a progress dialog before that for loop? Or how do you think I should go about it so that the database snapshot is retrieved in a timely manner? EDIT: Just saw your link, thank you. – Andrew Magana Jan 09 '17 at 17:02