1

On this post of solution, I can call the variable inside of void. When i tried to call it outside void , data is empty.

Link : I cant get the values from Firebase and put them in to TextView in fragment

I have already defined the variable as public.

EDIT :

public class FormSendActivity extends AppCompatActivity {

// form edit text
EditText email ;
EditText perihal;
EditText deskripsi;

TextView tes;

// variabel untuk menyimpan data dari edit text menjadi string
public String emails;
public String perihals;
public String deskripsis;

//variabel untuk menampung datauser sesuai login
public String getnama;
public String getusername;

FirebaseAuth firebaseAuth;
public String uid ;

Button kirim;

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


    email = (EditText) findViewById(R.id.editText);
    perihal = (EditText) findViewById(R.id.editText2);
    deskripsi = (EditText) findViewById(R.id.editText4);
    kirim = (Button) findViewById(R.id.button);
    tes = (TextView) findViewById(R.id.textView3);

    firebaseAuth = firebaseAuth.getInstance();
    uid = firebaseAuth.getCurrentUser().getUid();

    dapatdatauser(uid);  // here i call the method of bottom, and put in to a variabel
    tes.setText(getusername); //  here i put the variabel to textview to test

    kirim.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            emails = email.getText().toString();
            perihals = perihal.getText().toString();
            deskripsis = deskripsi.getText().toString();

            Sendmail sendmail = new Sendmail(emails,perihals,deskripsis);
            FirebaseDatabase.getInstance().getReference("Sendmail")
                    .child(getusername).child("Outbox").push()
                    .setValue(sendmail).addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()){
                        Toast.makeText(FormSendActivity.this,"Data sudah terkirim !!", Toast.LENGTH_SHORT).show();
                        Intent i = new Intent(FormSendActivity.this, MainActivity.class);
                        finish();
                    }else {
                        Toast.makeText(FormSendActivity.this,"Data gagal di kirim !!", Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
    });


}

public void dapatdatauser(String iduser){
    // Mendapatkan DataUsers Berdasarkan uid sesuai login
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
    DatabaseReference query = reference.child("DataUsers").child(iduser);
    ValueEventListener valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            // Memasukkan data kedalam variabel username
            getusername = dataSnapshot.child("username").getValue(String.class);

        }

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

        }
    };
    query.addListenerForSingleValueEvent(valueEventListener);
}} 

So here is my full code. I am calling the method dapatdatauser first (which inside the method is set as the value of variable 'getusername') then I set the variable to textview to test it. but the output is empty.

i found a solution to put all the code in method onCreate. and do the rest inside

public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        // Memasukkan data kedalam variabel username
        getusername = dataSnapshot.child("username").getValue(String.class);

    }

but i just want to know , why my code in the first place is not working ? thank you

3 Answers3

3

but i just want to know , why my code in the first not function ?

You can't get the getusername value, because it is async operations. The data hasn't finished loading from database and that's why it is not accessible.

John Joe
  • 12,412
  • 16
  • 70
  • 135
1

According to firestore documentation https://firebase.google.com/docs/functions/terminate-functions the Cloud Firestore is asynchronous so basically in your code you are populate the data before the query set the result in the variables, you have to run it in multi thread to avoid this issues or design the code to populate the data after the operation is finished.

i recommend you to see this post it's slimier to your condition.

Async with Firestore

YQadoome
  • 178
  • 14
0

OnCreate will be called when your object of this class is created so it is once in all operation. So this time your variables will be set only if they are initialized inside onCreate.

OnDataChange is listener and until data gets changed, you will not get this method called and variable set. Either you need to add

tes.setText(getusername); inside onDataChange, or

getusername = dataSnapshot.child("username").getValue(String.class);

inside onCreate before tes.setText(getusername);

John Joe
  • 12,412
  • 16
  • 70
  • 135
Jack
  • 193
  • 11