my image is stored inside firebase storage and its url is stored inside the realtime database. Firebase realtime and storage are both like this:
Type1
----Time1
--------elements of type1
----Time2
--------elements of type2
Type2
....
I let the users change element's time so I have to move an element from a branch to another.
My strategy is to create a new element on the new branch and then remove the old one.
The problem is in the creation of the new element in the chosen branch, specifically I have problems setting the image of the new element equal to that of the old one.
I tried to use Uri.parse() passing the url saved as string in the realtime database and I also tried to use storagereference.getdownloadurl, both I got this error:
could not locate file for uploading:https://firebasestorage.googleapis.com/v0/b/re...
E/StorageException: StorageException has occurred.
An unknown error occurred, please check the HTTP result code and inner exception for server response.
Code: -13000 HttpResult: 0
And it's not sense because If I click that link in the error, it shows me the correct image, so why it can't locate it?!
How can I do it?
storageReference = FirebaseStorage.getInstance().getReference().child("images/Anime/General/Test1");
storageReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
storageReference = FirebaseStorage.getInstance().getReference().child("images/Anime/Future/Test1");
storageReference.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
...
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
}
});
}
});
The error is on this line:
storageReference.putFile(uri)...
You have to download the bytes from firebase like this:
storageReference = FirebaseStorage.getInstance().getReference().child("images/Anime/General/Test1");
storageReference.getBytes(1024*1024).addOnSuccessListener(new OnSuccessListener<byte[]>() {
#Override
public void onSuccess(byte[] bytes) {
//here add new element in the server with storageReference.putbytes(bytes)..
}
});
Related
I'm trying to make a social media application with firebase in android studio, now my application is finished, it works smoothly, but there is a problem, there is a delete button on the shared post, when this button is clicked, I want it to delete only that selected picture.
Can you help me, please?
if you're asking about firebase database you can do something like
// Reference to the node you want to delete
DatabaseReference postRef = FirebaseDatabase.getInstance().getReference("posts").child(postId);
// Delete the node
postRef.removeValue();
in case you are talking about firebase storage you can do something like
// Reference to the image you want to delete
StorageReference imageRef = storageRef.child("images/myimage.jpg");
// Delete the image
imageRef.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
// File deleted successfully
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Uh-oh, an error occurred!
}
});
you must include the dependency in build.gradle
implementation 'com.google.firebase:firebase-storage:19.2.0'
sorry i didn't had enough reputation here to comment and ask so directly posting an answer
I have an error. when the user uploads his image. the other data were gone and only the profile URI is visible.
Currently, I have 5 strings
name
email
password
profile(image URI)
refer id
coins
However, when a user uploads their profile photo, all the data is removed.
showing only the profile image URI
I have attached the code here
private void updateUserProfile() {
Map<String,String > profile = new HashMap<>();
profile.put("profile",imageUri.toString());
database
.collection("Users") // the path of users.
.document(FirebaseAuth.getInstance().getUid()) // to update in the current users.
// .update(user)
.set(profile)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void unused) {
Toast.makeText(getContext(), "Photo Updated!", Toast.LENGTH_SHORT).show();
}
});
}
If you just looking to update a single field when can do so without using any Map values.
firestore.collection("YOUR_COLLECTION").document(user.getUid()).update("profile", imageUri.toString())
.addOnCompleteListener(task -> {
});
If you call .set(profile), you're replacing the existing data with whatever is in profile. If you want to merge the values in profile with any existing data in the document, use .update(profile) instead.
Also see the Firebase documentation on updating data in a document.
thanks for your answers. I already solved the problem. I have attached the codes below.
private void updateUserProfile() {
Map<String, Object> profile = new HashMap<>();
profile.put("profile", imageUri.toString());
final DocumentReference sDoc = database.collection("Users").document(FirebaseAuth.getInstance().getUid());
database.runTransaction(new Transaction.Function<Void>() {
#Override
public Void apply(#NonNull Transaction transaction) throws FirebaseFirestoreException {
DocumentSnapshot snapshot = transaction.get(sDoc);
transaction.update(sDoc, profile);
// transaction.update(sDoc, "name", binding.nameBox.getText() );
return null;
}
I am developing an application where a user can upload an image, and also a document. I can do write the code for uploading the image and that of the document separately, but what I want is to be able to upload an image and a document, get their download Urls place them in the realtime database at the same time. the code below is for uploading an image, how can I change it so that I can also upload a document and save the download URL in the same node as the image?
final StorageReference fileReference = storageReference.child(System.currentTimeMillis() + "." + getFileExtension(resultUri));
uploadTask = fileReference.putFile(resultUri);
uploadTask.continueWithTask(new Continuation(){
#Override
public Object then(#NonNull Task task) throws Exception {
if (!task.isComplete()){
throw Objects.requireNonNull(task.getException());
}
return fileReference.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task <Uri> task) {
if (task.isSuccessful()){
Uri downloadUri = task.getResult();
myUrl = downloadUri.toString();
String postid = reference.push().getKey();
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("image", myUrl);
//maybe add here the url of the document
//Is it possible to upload an image and a document, get their download Urls place them in the realtime database at the same time?
//hashMap.put("document", documentUrl);
hashMap.put("publisher",FirebaseAuth.getInstance().getCurrentUser().getUid());
hashMap.put("date", mDate);
reference.child(postid).setValue(hashMap);
loader.dismiss();
startActivity(new Intent(AskAQuestionActivity.this, MainActivity.class));
finish();
}else {
String error = task.getException().toString();
Toast.makeText(AskAQuestionActivity.this, "Failed" + error, Toast.LENGTH_SHORT).show();
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(AskAQuestionActivity.this, "Question could not be posted." , Toast.LENGTH_SHORT).show();
}
});
}else {
Toast.makeText(this, "No image is selected", Toast.LENGTH_SHORT).show();
}
}
Any Help will be really appreciated. Thank You.
How do I upload both an Image and a document to firebase storage, get the download URLs, and insert them into the realtime database simultaneously?
If you are thinking at a batch operation where you can add a Firebase Realtime Database setValue() operation and a Firebase Storage putFile() operation and make them work simultaneously, please note that this is not possible. These operations are apart of different Firebase services. Unfortunately, none of the Firebase products support cross-product transactional operations. So the only option that you have is the one that you are already using.
I want to get the Download Url from uploadTask.addOnProgressListener method of Firebase. How can I get the Download Url using following code?
UploadTask uploadTask = storageRef.putBytes(data);
uploadTask.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>()
{
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot)
{
Log.d("aaaaasessin",""+taskSnapshot.getTask().getResult());
}
});
I used taskSnapshot.getTask().getResult() but that is not working.
Edit Aug 22th 2019:
There is a new method recently added to StorageReference's class in the Android SDK named list().
To solve this, you need to loop over the ListResult and call getDownloadUrl() to get the download URLs of each file. Remember that getDownloadUrl() method is asynchronous, so it returns a Task object. See below for details. I have even written an article regarding this topic called:
How to upload an image to Cloud Storage and save the URL in Firestore?
In order to get the download url, you need to use addOnSuccessListener, like in the following lines of code:
uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
storageRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
String url = uri.toString();
//Do what you need to do with url
}
});
}
});
As in the Firebase release notes on May 23, 2018 is mentioned that:
Cloud Storage version 16.0.1
Removed the deprecated StorageMetadata.getDownloadUrl() and UploadTask.TaskSnapshot.getDownloadUrl() methods. To get a current download URL, use StorageReference.getDownloadUr().
So now when calling getDownloadUrl() on a StorageReference object it returns a Task object and not an Uri object anymore.
Please also rememeber, neither the success listener nor the failure listener (if you intend to use it), will be called if your device cannot reach Firebase Storage backend. The success/failure listeners will only be called once the data is committed to, or rejected by the Firebase servers.
How can I get file size from firebase storage before downloading it? I want to show file size to user so that they can see what is the exact size of the file.
I looked up https://firebase.google.com/docs/storage/android/download-files to check if there is any method to get particular file's size before downloading it. But I didn't find anything helpful.
Try this:
StorageReference ref = storage.getReference();
StorageReference reference = ref.child("images.jpg");
reference.getMetadata().addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
#Override
public void onSuccess(StorageMetadata storageMetadata) {
Log.i("The size of the file is:", storageMetadata.getSizeBytes());
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
}
});
Using getSizeBytes() you will be able to get the size of the file.
public long getSizeBytes ():
Returns
the stored Size in bytes of the StorageReference object
public StorageMetadata ():
Creates a StorageMetadata object to hold metadata for a StorageReference.
For more info check this:
https://developers.google.com/android/reference/com/google/firebase/storage/StorageMetadata.html
https://firebase.google.com/docs/storage/android/file-metadata
As posted on Firebase docs, you can get name, size, and content type of file stored on FirebaseStorage, by StorageReference getMetaData() method. According to Firebase docs,
File metadata contains common properties such as name, size, and
contentType (often referred to as MIME type) in addition to some less
common ones like contentDisposition and timeCreated. This metadata can
be retrieved from a Cloud Storage reference using the getMetadata()
method.
Here's the example how to access metadata of file stored on FirebaseStorage,
StorageReference storageRef = storage.getReference();
StorageReference forestRef = storageRef.child("images/forest.jpg");
forestRef.getMetadata().addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
#Override
public void onSuccess(StorageMetadata storageMetadata) {
//here, storageMetadata contains all details about your file stored on FirebaseStorage
Log.i("tag", "name of file: "+storageMetadata.getName());
Log.i("tag", "size of file in bytes: "+storageMetadata.getSizeBytes());
Log.i("tag", "content type of file: "+storageMetadata.getContentType());
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Uh-oh, an error occurred!
Log.i("tag", "Exception occur while gettig metadata: "+exception.toString());
}
});