user10158599
user10158599

Reputation:

Android: Why the value from firebase database is not being stored properly?

The code I am using to store the value of uid child from firebase database is as following:

lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                String data = (String) parent.getItemAtPosition(position);
                usersdRef.orderByChild("username").equalTo(parent.toString()).addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                        for(DataSnapshot data: dataSnapshot.getChildren()){
                           String dataUID = data.child("uid").getValue(String.class);
                            toUid = dataUID;
                        }
                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) {

                    }
                });

                Intent intent = new Intent(Main2Activity.this, Main5Activity.class);
                intent.putExtra("valueName", data);
                intent.putExtra("valueUID",toUid);
                startActivity(intent);

            }
        });

But when I try to use the value in different activity, the value is passed as null. I obtain and use the value as:

Bundle bundle = getIntent().getExtras();
        assert bundle != null;
        final String hName = bundle.getString("valueName");
        final String td = bundle.getString("valueUID");

hName is stored perfectly but td is passed as null.

The firebase database looks something like this:

firebase database

Upvotes: 0

Views: 400

Answers (2)

Alex Mamo
Alex Mamo

Reputation: 138824

To solve this problem, please use the following code:

lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        String data = (String) parent.getItemAtPosition(position);

        String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
        DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
        DatabaseReference uidRef = rootRef.child("users").child(uid);
        ValueEventListener valueEventListener = new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                String dataUID = dataSnapshot.child("uid").getValue(String.class);
                String dataUsername = dataSnapshot.child("username").getValue(String.class);

                Intent intent = new Intent(Main2Activity.this, Main5Activity.class);
                intent.putExtra("valueUID",dataUID);
                intent.putExtra("valueName", dataUsername);
                startActivity(intent);
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                Log.d(TAG, databaseError.getMessage());
            }
        };
        uidRef.addListenerForSingleValueEvent(valueEventListener);
    }
});

Instead of query the entire database to find a single user, which is a waste of time and resources you can get a reference of that particular user using his uid. So there is no need to use getChildren() method to loop through the DataSnapshot object, since you can simply get it without a loop. It is true, onDataChange() method has an asynchronous behavior and all the code regarding the intent should placed inside the callback. If you want to use those values outside, I recommend you see the last part of my anwser from this post in which I have explained how it can be done using a custom callback. You can also take a look at this video for a better understanding.

Upvotes: 0

jujka
jujka

Reputation: 1217

It is because you are trying to access value of variable toUid outside the actual callback. Callback meant to be async, meaning you can not just access it's result on the next line after it's definition. Your code is ok, but as an idea, access this variable inside callback method, not beneath the callback itself

lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

        String data = (String) parent.getItemAtPosition(position);
        usersdRef.orderByChild("username").equalTo(parent.toString()).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                for(DataSnapshot data: dataSnapshot.getChildren()){
                   String dataUID = data.child("uid").getValue(String.class);
                   toUid = dataUID;

                   Intent intent = new Intent(Main2Activity.this, Main5Activity.class);
                   intent.putExtra("valueName", data);
                   intent.putExtra("valueUID",toUid);
                   startActivity(intent);
            }
        }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
    }
});

Upvotes: 1

Related Questions