I created an app and I want to store some images in a Firebase Storage, this is working fine, those images are uploaded, but I want to save their path in the database and those values are not inserted.
Let me show you what I did:
I'm not showing you the entire function. Only the code that points to my problem.
List<String> picturesUrls = new ArrayList<String>(); //This is declared globaly
buttonSigningUp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
uploadFile(mProfilePic,"profilePicture");
uploadFile(mIdPhoto,"idPicture");
uploadFile(mCriminalRecord,"criminalRecordPicture");
final List<String> pictureUrls = picturesUrls;
mFirebaseAuth.createUserWithEmailAndPassword(email, password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if(task.isSuccessful()) {
final CarrierUser carrierUser;
carrierUser = new CarrierUser(
pictureUrls
);
FirebaseDatabase.getInstance().getReference("User")
.child(FirebaseAuth.getInstance().getCurrentUser().getUid()).setValue(carrierUser).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful()) {
Toast.makeText(SignupCarrier.this,"Your request has been sent for approval", Toast.LENGTH_LONG).show();
sendEmail(email, fullname);
openLogin();
}
}
});
}
}
});
}
});
Upload File Function :
private void uploadFile(Uri path,String forWho) {
if(path != null) {
StorageReference fileReference = mStorageRef.child(editemail.getText().toString()+"-"+forWho+"-"+System.currentTimeMillis()+"."+getFileExtension(path));
mUploadTask = fileReference.putFile(path)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
picturesUrls.add(taskSnapshot.getUploadSessionUri().toString());
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(SignupCarrier.this, e.getMessage(),Toast.LENGTH_LONG).show();
}
});
}
}
And the Object:
import java.util.List;
public class CarrierUser {
public List<String> picturesUrls;
public CarrierUser() {
}
public CarrierUser(List<String> picturesUrls) {
this.picturesUrls = picturesUrls;
}
}
I do have another values and fields, but they are inserted, only this list with paths is not. Maybe I did something wrong when I add a path to that list, but I can't figure out what exactly is wrong. Can you please help me out? Thank you very much.
Related
So I have a simple ecommerce app that has products(custom objects) on the cart and a proceed to checkout button. When the button is pressed I send an ArrayList with product ids with the intent so I can access them when confirming the order.
Now I need to loop through this list and make a separate order for each item on firebase(because there a are multiple venders involved). But when I do this it keeps duplicating the list of items on my home screen when it opens it as though its an infinite loop that keeps calling the home screen intent.
So here is the ConfirmOrderActivity confirmOrder code
private void confirmOrder() {
loadingBar.show();
String locationJson = null;
if (useCurrentLocation.isChecked()){
Gson gson = new Gson();
locationJson = gson.toJson(location);
}
final String saveCurrentDate, saveCurrentTime;
Calendar callForDate = Calendar.getInstance();
SimpleDateFormat currentDate = new SimpleDateFormat("MMM dd, yyyy");
saveCurrentDate = currentDate.format(callForDate.getTime());
SimpleDateFormat currentTime = new SimpleDateFormat("HH:mm:ss a");
saveCurrentTime = currentTime.format(callForDate.getTime());
final DatabaseReference ordersRef = FirebaseDatabase.getInstance().getReference()
.child("Orders")
.child(Prevalent.currentOnlineUsr.getPhone());
DatabaseReference productsRef = FirebaseDatabase.getInstance().getReference().child("Products");
for (String ID : products) {
String orderID = UUID.randomUUID().toString();
String finalLocationJson = locationJson;
productsRef.child(ID).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
ProductModel model = snapshot.getValue(ProductModel.class);
AdminOrder order = new AdminOrder();
order.setOrderID(orderID);
order.setTotalAmount(model.getPrice());
order.setName(deliveryName.getText().toString());
order.setPhone(deliveryPhone.getText().toString());
order.setUid(Prevalent.currentOnlineUsr.getPhone());
order.setCity(deliveryCity.getText().toString());
order.setAddress(deliveryAddress.getText().toString());
if (useCurrentLocation.isChecked()) {
order.setLocation(finalLocationJson);
}
order.setDate(saveCurrentDate);
order.setTime(saveCurrentTime);
order.setState("Not delivered");
order.setMerchantID(model.getMerchantID());
order.setProduct(model.getPname());
order.setProductID(model.getPid());
ordersRef.child(ID).child(orderID).setValue(order).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
FirebaseDatabase.getInstance().getReference()
.child("Cart")
.child("user")
.child(Prevalent.currentOnlineUsr.getPhone())
.removeValue()
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
removeProductsFromDB(products);
loadingBar.dismiss();
showToast("Order Placed");
Intent intent = new Intent(ConfirmOrderActivity.this, HomeActivity.class);
startActivity(intent);
finish();
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
showToast("Failed");
loadingBar.dismiss();
}
});
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
showToast("Failed");
loadingBar.dismiss();
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
I am new to programming so I am sure there should be a better way of doing this.
Thanks in advance.
I have uploaded 1 Hashmap to firestore.And when i try to upload one more Hashmap to the same document it replaces my previous Hashmap.Why is it so?
I change the String title everytime and still it replaces the previous Hashmap.
String poll1 = Poll1.getText().toString().trim();
String poll2 = Poll2.getText().toString().trim();
String poll3 = Poll3.getText().toString().trim();
String title = Title.getText().toString().trim();
DocumentReference documentReference = firestore.collection("Polls").document("abc1");
Map<String, Object> nestedData = new HashMap<>();
nestedData.put(poll1 , 0 );
nestedData.put(poll2 , 0);
nestedData.put(poll3 , 0);
Map<String, Object> upload = new HashMap<>();
upload.put(title, nestedData);
documentReference.set(upload).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Toast.makeText(polls.this, "UPLOADED", Toast.LENGTH_LONG).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(polls.this, "FAILED", Toast.LENGTH_LONG).show();
}
});
your document needs to mention that this has to be merged instead replace.
.set(data, SetOptions.merge())
Try this if it works.
documentReference.set(upload, SetOptions.merge()).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Toast.makeText(polls.this, "UPLOADED", Toast.LENGTH_LONG).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(polls.this, "FAILED", Toast.LENGTH_LONG).show();
}
});
I'm trying to upload some images to firestore storage and put the image URL to firebase database. The images are uploading successfully but the image URLs aren't being added to the database. The problem that I think might be causing this is that the image URL is being added to the Hashmap after uploading the image but the database upload process isn't waiting for the URL instead, adding all other HashMap keys to the database before the Upload task returns the URL. This way all other keys get added to the database but not the Image URLs. In the below code product id is being added successfully to the database, also if I leave any image unselected its url alse gets added as empty to the database which is working fine but if I select an image to upload, The hashmap to database upload finishes even before getting the uploaded image URL.
public class AddProductDataActivity extends AppCompatActivity {
String productId;
EditText productIdEditText;
ImageView addProductImage3;
Button addProductSubmit;
final int IMAGE3_REQUEST = 30;
Uri image3LocationPath;
StorageReference objectStorageReference;
FirebaseFirestore objectFireBaseFireStore;
Map<String, String> objectMap = new HashMap<>();
StorageReference img3Store;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_product_data);
brandNameEditText =(EditText)
addProductImage3 = (ImageView) findViewById(R.id.add_product_image3);
objectStorageReference =
FirebaseStorage.getInstance().getReference("images");
objectFireBaseFireStore = FirebaseFirestore.getInstance();
addProductImage3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent objectIntent = new Intent();
objectIntent.setType("image/*");
objectIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(objectIntent, IMAGE3_REQUEST);
}
});
addProductSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
productId = productIdEditText.getText().toString();
if(image3LocationPath != null)
{
final String image3Name = productId + "_image3." + getExtension(image3LocationPath);
img3Store = objectStorageReference.child(image3Name);
UploadTask imageUploadTask = img3Store.putFile(image3LocationPath);
imageUploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
#Override
public Task<Uri> then(#NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if(!task.isSuccessful())
{
Toast.makeText(AddProductDataActivity.this, "Task Unsuccessful", Toast.LENGTH_SHORT).show();
}
return img3Store.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if(task.isSuccessful())
{
String image_3_url = task.getResult().toString();
objectMap.put("image3_url",image_3_url);
}
else
{
Toast.makeText(AddProductDataActivity.this, task.getException().toString(), Toast.LENGTH_SHORT).show();
}
}
});
}
else
{
objectMap.put("image3_url","");
}
objectFireBaseFireStore.collection("images").document(productId).set(objectMap).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(AddProductDataActivity.this, "Product Added Successfully.", Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(AddProductDataActivity.this, "Error in Adding Product. Please Try Again.\n"+e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode){
case 30:
try
{
if(resultCode == RESULT_OK && data != null && data.getData() != null)
{
image3LocationPath = data.getData();
Bitmap objectBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), image3LocationPath);
addProductImage3.setImageBitmap(objectBitmap);
}
}
catch (Exception e)
{
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
private String getExtension(Uri uri){
try
{
ContentResolver objectContentResolver = getContentResolver();
MimeTypeMap objectMimeTypeMap = MimeTypeMap.getSingleton();
return objectMimeTypeMap.getExtensionFromMimeType(objectContentResolver.getType(uri));
}
catch (Exception e)
{
Toast.makeText(AddProductDataActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
return null;
}
}
}
Your code
objectFireBaseFireStore.collection("images").document(productId).set(objectMap)
executes before
objectMap.put("image3_url",image_3_url)
Which means when you are setting your url, your objectMap does not have the key image3_url
Try to set values to database inside onComplete() or use different workaround to set only the url.
You forgot to add your HashMap to Database Reference of Firebase.
This is reference from my current project code.
private void uploadVideo() {
StorageReference mStorageRef = FirebaseStorage.getInstance().getReference();
final StorageReference riversRef = mStorageRef.child(Constants.STORAGE_PATH + "/" + mFinalUploadUri.getLastPathSegment());
riversRef.putFile(mFinalUploadUri).continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
#Override
public Task<Uri> then(#NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if (!task.isSuccessful()) {
throw Objects.requireNonNull(task.getException());
}
// Continue with the task to get the download URL
return riversRef.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
FirebaseFirestore database = FirebaseFirestore.getInstance();
String mSelectedCategory = binding.categorySpinner.getSelectedItem().toString();
DocumentReference newDocumentReference = database.collection(PENDING_PATH).document();
VideoModel videoModel = new VideoModel();
videoModel.setDocumentId(newDocumentReference.getId());
videoModel.setTitle(mTitle);
videoModel.setCategory(mSelectedCategory);
//videoModel.setTime(FieldValue.serverTimestamp());
videoModel.setUrl(downloadUri != null ? downloadUri.toString() : null);
newDocumentReference.set(videoModel).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
binding.progressBar.setVisibility(View.GONE);
binding.button.setVisibility(View.VISIBLE);
binding.videoView.setVisibility(View.GONE);
selectedUri = null;
Toast.makeText(AdminVideoUploadActivity.this, R.string.uploaded_successfully, Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(AdminVideoUploadActivity.this, R.string.failed_to_upload, Toast.LENGTH_SHORT).show();
}
});
}
}
});
}
Now you can check code and find where you have done mistake. Just add lines of code of inserting in database.
Thank you.
How can I check whether my data has been successfully pushed to Firebase?
I want to push my data like the picture
To know when the write operation is completed or not, you need to use a complete listener. So let's say you want to know when the write operation for your id_data property is completed, please use the followig code:
addReference.child("DataInputManual").child(key).child("id_data").setValue(key)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
//Do what you need to do
} else {
Log.d(TAG, task.getException().getMessage());
}
}
});
You can also use a success listener like this:
addReference.child("DataInputManual").child(key).child("id_data").setValue(key)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
//Do what you need to do
}
});
You can use below code to check success or failure of upload on firebase Storage.
final StorageReference photoRef = FirebaseStorage.getInstance().getReference()
.child("image_folder_on_firebase")
.child("image_name" + ".jpeg");
photoRef.putFile("local pic uri( Object of Uri)").addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
newPicFirebaseUri = taskSnapshot.getStorage().getDownloadUrl().getResult();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
}
});
I'm storing multiple images at once in Firebase Storage and I need to get the URL of each one of them in the Firebase databse.
Here's the code:
private void SaveVersus() {
comment = Comment.getText().toString();
if (imageUri==null||imageUri2==null){
Toast.makeText(this, "...Select a Image...", Toast.LENGTH_SHORT).show();
}
else if(imageUri!=null&&imageUri2!=null&&imageUri3==null&&imageUri4==null) {
//Save2ImagesFirebase();
List<Uri> uri = Arrays.asList(imageUri,imageUri2);
storeMultipleImages(uri);
}
else if(imageUri!=null&&imageUri2!=null&&imageUri3!=null&&imageUri4==null){
//Save3ImagesFirebase();
List<Uri> uri2 = Arrays.asList(imageUri,imageUri2,imageUri3);
storeMultipleImages(uri2);
}
else if(imageUri!=null&&imageUri2!=null&&imageUri3!=null&&imageUri4!=null){
//Save4ImagesFirebase();
List<Uri> uri3 = Arrays.asList(imageUri,imageUri2,imageUri3,imageUri4);
storeMultipleImages(uri3);
}
}
public void storeImage(Uri imageUri) {
StorageReference filepath = mStorage.child("Versus Images").child(imageUri.getLastPathSegment());
filepath.putFile(imageUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if (task.isSuccessful()){
downloadURL = task.getResult().getUploadSessionUri().toString();
Toast.makeText(ImageVersus.this, "Versus Published", Toast.LENGTH_SHORT).show();
GetInDB();
}
else{
Toast.makeText(ImageVersus.this, "..Error..", Toast.LENGTH_SHORT).show();
}
}
});
}
private void GetInDB() {
mDatabase.child(current_userID).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
String username = dataSnapshot.child("Username").getValue().toString();
HashMap InfoMap = new HashMap<>();
InfoMap.put("username",username);
InfoMap.put("imageUrl",downloadURL);
versusDBRef.child(current_userID).updateChildren(InfoMap);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
public void storeMultipleImages(List<Uri> imageUris) {
for (Uri uri : imageUris) {
storeImage(uri);
}
}
The problem is that, in the hashmap, I can only put the URL of one image and I need to get multiple URLs depending on what the amount of pictures the user select, if they chose two, then in the hashmap must be two URL's and so on.