0

I'm writing an Android App that deals with houses and in this specific class I'm trying to get a houses values from Firebase Realtime database and then out those values into TextViews. For some reason the Strings I'm using to hold the values won't hold the values I'm giving to them. Any help would be greatly appreciated.

package com.example.shamwari;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

public class property_view_agent extends AppCompatActivity {

    private String name;
    private String address;
    private String category;
    private String size;
    private String price;

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

        setValues();
    }

    private void setValues() {
        DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
        DatabaseReference propRef = rootRef.child("Properties").child(globals.chosenProp);

        propRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()) {
                    for (DataSnapshot ds : dataSnapshot.getChildren()) {
                        String key = ds.getKey();

                        switch(key) {
                            case "name":
                                name = ds.getValue().toString();
                                Toast.makeText(getApplicationContext(),"In method name = " + name,Toast.LENGTH_SHORT).show();
                                break;
                            case "address":
                                address = ds.getValue().toString();
                                break;
                            case "category":
                                category = ds.getValue().toString();
                                break;
                            case "size":
                                size = ds.getValue().toString();
                                break;
                            case "price":
                                price = ds.getValue().toString();
                                break;
                            case "agent":
                                break;
                            default:
                                throw new IllegalStateException("Unexpected value: " + key);
                        }
                    }
                }
            }

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

        Toast.makeText(getApplicationContext(),"After method name = " + name,Toast.LENGTH_SHORT).show();

        loadDetails();
    }

    private void loadDetails() {
        TextView tvName = (TextView) findViewById(R.id.tvPropertyName);
        TextView tvAddress = (TextView) findViewById(R.id.tvFullAddress);
        TextView tvCategory = (TextView) findViewById(R.id.tvPropCategory);
        TextView tvSize = (TextView) findViewById(R.id.tvRoomSize);
        TextView tvPrice = (TextView) findViewById(R.id.tvPropPrice);

        Toast.makeText(getApplicationContext(),"Before setting method name = " + name,Toast.LENGTH_SHORT).show();

        tvName.setText(name);
        tvAddress.setText(address);
        tvCategory.setText(category);
        tvSize.setText(size + "m2");
        tvPrice.setText(price + ".00");
    }

    public void deleteProp(View view) {

    }

    public void goToAgentHome(View view) {
        Intent intent = new Intent(this, agent_home.class);
        startActivity(intent);
    }
}

As you can see the code is simple enough. When the activity is loaded the setValues() method is called which runs a DataSnapshot and collects the values I need from firebase. I suspect that the issue derives from the fact that the onDataChange method to fetch values from Realtime Database is encased in its own class. The switch statement does work (I've tested it with Toasts and the values seem to be set).

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
Anon5678
  • 27
  • 4
  • This [answer](https://stackoverflow.com/questions/47847694/how-to-return-datasnapshot-value-as-a-result-of-a-method/47853774) will help. – Alex Mamo May 26 '21 at 08:54

2 Answers2

2

You see the wrong data because the data are fetched asynchronously and you are calling loadDetails() before the callback has been invoked. This is a "timeline" of what's happening in your flow:

Ask data to Firebase -> invoke loadDetails() -> receive data from firebase -> set value of activity properties.

To fix this problem, move loadDetails() inside the callback like this

...
propRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            if (dataSnapshot.exists()) {
                ...
                loadDetails();
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) { }
    });
...
Jameido
  • 1,344
  • 1
  • 11
  • 21
2

You have to call loadDetails() method from onDataChange. The reason is, onDataChange method is not executing before your call