Issue
Here i read some input which i want to use for creating "Produs" object which i upload it to the firebase storage, then i want to retrieve it to display a list of objects, i have a problem when i want to update the path to the image storage, to retrieve it later.
public class Add extends AppCompatActivity {
DatabaseReference mDatabase;
EditText etNume, etCantitate, etPret;
Button btnSubmit, btnImage;
Uri mImage;
ImageView ivTest;
public static String path="";
StorageReference mStorageRef;
final int GALLERY_INTENT = 2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
mDatabase = FirebaseDatabase.getInstance().getReference();
etNume = findViewById(R.id.etNume);
etCantitate = findViewById(R.id.etCantitate);
etPret = findViewById(R.id.etPret);
btnSubmit = findViewById(R.id.btnSubmit);
btnImage = findViewById(R.id.btnImage);
ivTest =findViewById(R.id.ivTest);
mStorageRef = FirebaseStorage.getInstance().getReference();
btnImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.setType("image/*");
startActivityForResult(i, GALLERY_INTENT);
}
});
btnSubmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String nume, pret,cantitate;
nume = etNume.getText().toString().trim();
pret = etPret.getText().toString().trim();
cantitate = etCantitate.getText().toString().trim();
if(TextUtils.isEmpty(nume)){
etNume.setError("Email is required.");
return;
}
if(TextUtils.isEmpty(pret)){
etPret.setError("Email is required.");
return;
}
if(TextUtils.isEmpty(cantitate)){
etCantitate.setError("Email is required.");
return;
}
StorageReference file = mStorageRef.child("Produs").child(nume + ".jpg");
file.putFile(mImage).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
path += taskSnapshot.getMetadata().toString(); /// good path
Toast.makeText(Add.this, path, Toast.LENGTH_SHORT).show();
}
});
Toast.makeText(Add.this, path, Toast.LENGTH_SHORT).show();/// null path
Produs p=new Produs(nume,cantitate,pret,path);
Task task =mDatabase.child("Produs").child(nume).setValue(p);
task.addOnSuccessListener(new OnSuccessListener() {
@Override
public void onSuccess(Object o) {
Toast.makeText(Add.this, "Produsul a fost adaugat cu succes", Toast.LENGTH_SHORT).show();
startActivity(new Intent(getApplicationContext(),MainActivity.class));
}
});
task.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(Add.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == GALLERY_INTENT && resultCode == RESULT_OK && data != null && data.getData() != null){
mImage = data.getData();
ivTest.setImageURI(mImage);
}
}
}
How to have path changed from the onSuccess method? Basically i want to change the path after i upload an image to build " Produs " object Also, this is the good path to the image storage? As taskSnapshot.getdownloadURL() doesn't work for me.
Solution
The problem is not where you set and read the path variable, the problem is when you do this. Since the getDownloadURL() method makes a call to the server, its onSuccess may run much later than you think.
If you're seeing the wrong value for path, it's very likely that the onSuccess that sets it hasn't run yet. The easiest way to verify that is by either setting breakpoints on the read and write and running in a debugger, or by adding some logging and checking the order of that in your logcat.
The solution for this type of problem is always the same: any code that needs the download URL, needs to either be inside onSuccess, be called from there, or be synchronized in some other way.
So in your case, move the `` into the onSuccess:
StorageReference file = mStorageRef.child("Produs").child(nume + ".jpg");
file.putFile(mImage).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
path += taskSnapshot.getMetadata().toString(); /// good path
Toast.makeText(Add.this, path, Toast.LENGTH_SHORT).show();
Toast.makeText(Add.this, path, Toast.LENGTH_SHORT).show();
Produs p=new Produs(nume,cantitate,pret,path);
Task task =mDatabase.child("Produs").child(nume).setValue(p);
task.addOnSuccessListener(new OnSuccessListener() {
...
});
task.addOnFailureListener(new OnFailureListener() {
...
});
}
});
For more on this, see:
- How to store download image url in realtime database firebase android
- How to store Url into ArrayList from Firebase Storage?
- Can someone help me with logic of the firebase on success listener
- getContactsFromFirebase() method return an empty list
- Setting Singleton property value in Firebase Listener
Not all of these are directly about Cloud Storage for Firebase, but the explanation applies here as well.
Answered By - Frank van Puffelen
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.