I'm having a weird problem with Firebase in Android. I'm trying to upload a photo to Firebase Storage and I'm getting the following error:
E/UncaughtException: java.lang.IllegalArgumentException: The supplied bucketname is not available to this project.
At this line of code:
StorageReference mStorageRef = mFirebaseStorage.getReferenceFromUrl("gs://mooseandroid-a9f96.appspot.com");
I'm sure that the bucketname is the same as the one in the console. I even tried with a bucketname that works fine in iOS with Swift. I also changed the rules to public so anyone can read and write to this storage bucket. The realtime database works fine for this project. I'm running out of options right now, don't even know what else I could be trying.
Here's the whole piece of code:
FirebaseStorage mFirebaseStorage = FirebaseStorage.getInstance();
StorageReference mStorageRef = mFirebaseStorage.getReferenceFromUrl("gs://mooseandroid-a9f96.appspot.com");
final StorageReference photoRef = mStorageRef.child("posts_images/mooseImg" + getCurrentDateTime() + ".jpg");
UploadTask uploadTask = photoRef.putBytes(data);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle unsuccessful uploads
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// taskSnapshot.getMetadata() contains file metadata such as size, content-type, and download URL.
});
And here's the whole error:
E/UncaughtException: java.lang.IllegalArgumentException: The supplied bucketname is not available to this project.
at com.google.android.gms.common.internal.zzaa.zzb(Unknown Source)
at com.google.firebase.storage.FirebaseStorage.zzz(Unknown Source)
at com.google.firebase.storage.FirebaseStorage.getReferenceFromUrl(Unknown Source)
at com.moose.android.AddPostActivity.onClick(AddPostActivity.java:163)
at android.view.View.performClick(View.java:5702)
at android.widget.TextView.performClick(TextView.java:10888)
at android.view.View$PerformClick.run(View.java:22541)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
The documentation for getReferenceFromUrl(String fullUrl) states:
An error is thrown if fullUrl is not associated with the FirebaseApp
used to initialize this FirebaseStorage
Use this code to see the bucket name in your FirebaseApp:
FirebaseOptions opts = FirebaseApp.getInstance().getOptions();
Log.i(TAG, "Bucket = " + opts.getStorageBucket());
I expect it will not be mooseandroid-a9f96.appspot.com and will instead be the storage_bucket value in the project_info section of your google-services.json file:
"project_info": {
"project_number": "816275527980",
"firebase_url": "https://project-8693710910123456789.firebaseio.com",
"project_id": "project-8693710910123456789",
"storage_bucket": "project-8693710910123456789.appspot.com"
},
If anyone changes the bucket url afterwards just clean and rebuild the android project, it solved the issue for me.
For cleaning go to Build tab on top nav bar in android studio -> Click Clean Project.
For rebuilding again go to Build tab on top nav bar in android studio -> Click Rebuild Project.
Related
i'm trying to get profile picture for every user from firebase storage within a firestore recycler adapter. i'm using the glide library to load the picture on the imageview. But i'm getting a StorageException. I always used the same code before to get picture from Firebase Storage but now i don't know what does changed.
Here's my code:
#Override
protected void onBindViewHolder(#NonNull UsersViewHolder usersViewHolder, int i, #NonNull User user) {
FirestoreUsage.getUserPictureReference(user.getMail(), user.getGender()).child("profile_picture.jpg").getDownloadUrl()
.addOnSuccessListener(uri -> Glide.with(context).load(uri)
.into(usersViewHolder.image));
usersViewHolder.name.setText(user.getName());
usersViewHolder.city.setText(user.getCity());
}
// ONE USER STORAGE REFERENCE
public static StorageReference getUserPictureReference(String userMail, String gender) {
return getAllUsersStorageRef().child(gender).child(userMail).child("PROFILE PICTURE");
}
And here is the exception:
E/StorageException: StorageException has occurred.
Object does not exist at location.
Code: -13010 HttpResult: 404
E/StorageException: { "error": { "code": 404, "message": "Not Found. Could not get object", "status": "GET_OBJECT" }}
java.io.IOException: { "error": { "code": 404, "message": "Not Found. Could not get object", "status": "GET_OBJECT" }}
at com.google.firebase.storage.network.NetworkRequest.parseResponse(NetworkRequest.java:434)
at com.google.firebase.storage.network.NetworkRequest.parseErrorResponse(NetworkRequest.java:451)
at com.google.firebase.storage.network.NetworkRequest.processResponseStream(NetworkRequest.java:442)
at com.google.firebase.storage.network.NetworkRequest.performRequest(NetworkRequest.java:272)
at com.google.firebase.storage.network.NetworkRequest.performRequest(NetworkRequest.java:286)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(ExponentialBackoffSender.java:70)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(ExponentialBackoffSender.java:62)
at com.google.firebase.storage.GetDownloadUrlTask.run(GetDownloadUrlTask.java:76)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
Please help me
I have found a solution for my problem. It was about path.
Earlier, when i was registrating the profil picture of the user in firebase storage, i also saved the path of the picture in firestore.
StorageReference userProfilePicture = FirestoreUsage.getUserPictureReference(Prevalent.currentUserOnline.getMail(), gender).child("profile_picture.jpg");
userProfilePicture.putFile(uriImageSelected).addOnSuccessListener(this, taskSnapshot -> {
String pathImageSavedInFirebaseStorage = Objects.requireNonNull(taskSnapshot.getMetadata()).getPath();
choiceMap.put("profile_picture", pathImageSavedInFirebaseStorage);
Prevalent.currentUserOnline.setProfile_picture(pathImageSavedInFirebaseStorage);
Then in my adapter, i created a Storage Reference with that path and dowloaded the pic
StorageReference storageReference = FirebaseStorage.getInstance().getReference(user.getProfile_picture());
storageReference.getDownloadUrl().addOnSuccessListener(uri -> Glide.with(context).load(uri)
.into(usersViewHolder.image));
I have made a social media app where users can upload there pic. I want to add a delete option for the users in the app. I want the users to delete their pic from Firebase cloud storage whenever needed. Here is my code
val firebase_url = contentDTOs[p1].imageUrl
val storageRef =
firebase_url?.let { it1 ->
FirebaseFirestore.getInstance().collection("images").document(
it1
)
}
storageRef?.delete()?.addOnSuccessListener {
// File deleted successfully
Toast.makeText(context , "Deleted",Toast.LENGTH_SHORT).show()
}?.addOnFailureListener {
// Uh-oh, an error occurred!
Toast.makeText(context , "cannot delete",Toast.LENGTH_SHORT).show()
}
return#setOnLongClickListener true
But whenever I try to delete any image it returns me an error
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.videoapp, PID: 20522
java.lang.IllegalArgumentException: Invalid path (https://firebasestorage.googleapis.com/v0/b/video-app-af9bf.appspot.com/o/images%2FIMAGE_20201023_144632_.png?alt=media&token=9cd9d400-49ed-4f73-81b3-baa7668a8430). Paths must not contain // in them.
I think it's because you have
images%2FIMAGE_20201023_144632
fragment in your link. And %2F is encoded backslash. Unfortunately from your code is not clear, how this link is formed
I know this is a discussed topic, but here I am, after all other solutions I've found did not solve my problem. I saved multiple images in Firebase Storage and now I want to get one of them and put it into an ImageView on an AlertDialog (or another Activity).
I've read about Glide solution, but it doesn't work for me. Gilde:
Glide.with(ViewScenesSG.this) //ViewScenesSG is the Activity
.load(reference) //the storage reference
.into(imageView); //my imageView
Dependencies for Glide (I've tried with multiple versions and 4.8.0 is the only one that doesn't give me Build error):
implementation 'com.github.bumptech.glide:glide:4.8.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
annotationProcessor 'androidx.annotation:annotation:1.1.0'
I've also read about the .using(new FirebaseImageLoader()) method, I've implemented the FirebaseImageLoader(), but the using() method is not found => build error. I believe it's been removed.
The second version I've tried is this one (found in another question here):
final long ONE_MEGABYTE = 1024 * 1024;
reference.getBytes(ONE_MEGABYTE)
.addOnSuccessListener(new OnSuccessListener<byte[]>() {
#Override
public void onSuccess(byte[] bytes) {
Bitmap bm = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
imageView.setMinimumHeight(dm.heightPixels);
imageView.setMinimumWidth(dm.widthPixels);
imageView.setImageBitmap(bm);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Toast.makeText(ViewScenesSG.this, "Couldn't retrieve image.", Toast.LENGTH_SHORT).show();
}
});
But every time it goes on the Failure listener. Therefore, my imageView always remains empty.
In my logcat I observed this error:
E/StorageException: Could not open resulting stream.
java.io.IOException: Could not open resulting stream.
at com.google.firebase.storage.StreamDownloadTask.createDownloadStream(com.google.firebase:firebase-storage##19.1.1:145)
at com.google.firebase.storage.StreamDownloadTask.access$000(com.google.firebase:firebase-storage##19.1.1:36)
at com.google.firebase.storage.StreamDownloadTask$1.call(com.google.firebase:firebase-storage##19.1.1:167)
at com.google.firebase.storage.StreamDownloadTask$1.call(com.google.firebase:firebase-storage##19.1.1:164)
at com.google.firebase.storage.StreamDownloadTask$StreamProgressWrapper.ensureStream(com.google.firebase:firebase-storage##19.1.1:325)
at com.google.firebase.storage.StreamDownloadTask$StreamProgressWrapper.access$100(com.google.firebase:firebase-storage##19.1.1:262)
at com.google.firebase.storage.StreamDownloadTask.run(com.google.firebase:firebase-storage##19.1.1:175)
at com.google.firebase.storage.StorageTask.lambda$getRunnable$7(com.google.firebase:firebase-storage##19.1.1:1072)
at com.google.firebase.storage.StorageTask$$Lambda$12.run(Unknown Source:2)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
E/StorageException: StorageException has occurred.
Object does not exist at location.
Code: -13010 HttpResult: 404
But the image is there, in the Storage, and the reference points directly to it:
storageRef = storage.getReference("photos").child(title); //for all images in the current folder named with the 'title' attribute
StorageReference reference = storageRef.child(imageName); //for the image I want to retrieve
What am I missing?
EDIT: Using the suggestion in the coments, I tried with:
reference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Glide.with(ViewScenesSG.this)
.load(uri.toString())
.into(imageView);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(ViewScenesSG.this, "Retrieving image failed",
Toast.LENGTH_SHORT).show();
}
});
but this time I get the error:
E/StorageException: { "error": { "code": 404, "message": "Not Found. Could not get object", "status": "GET_OBJECT" }}
java.io.IOException: { "error": { "code": 404, "message": "Not Found. Could not get object", "status": "GET_OBJECT" }}
at com.google.firebase.storage.network.NetworkRequest.parseResponse(com.google.firebase:firebase-storage##19.1.1:433)
at com.google.firebase.storage.network.NetworkRequest.parseErrorResponse(com.google.firebase:firebase-storage##19.1.1:450)
at com.google.firebase.storage.network.NetworkRequest.processResponseStream(com.google.firebase:firebase-storage##19.1.1:441)
at com.google.firebase.storage.network.NetworkRequest.performRequest(com.google.firebase:firebase-storage##19.1.1:272)
at com.google.firebase.storage.network.NetworkRequest.performRequest(com.google.firebase:firebase-storage##19.1.1:286)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(com.google.firebase:firebase-storage##19.1.1:70)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(com.google.firebase:firebase-storage##19.1.1:62)
at com.google.firebase.storage.GetDownloadUrlTask.run(com.google.firebase:firebase-storage##19.1.1:76)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
I found the following solution (as suggested in the comments before):
Using the Firebase UI plugin with Gilde, I added the following dependency:
implementation 'com.firebaseui:firebase-ui-storage:6.2.0'
Now, having the StorageReference reference pointing to the image, and the ImageView in which the content must be uploaded, the following code retrieves the image and puts it in the ImageView:
Glide.with(ViewScenesSG.this) //this is the current Activity
.load(reference)
.into(imageView);
To be mentioned that the ImageView must have the dimensions set to a specific value, not using wrap_content or match_parent (at least for height in my case), otherwise it will appear as a small icon. This can also depend on how the image was saved before in the Storage.
Hope this will help someone else as well!
I'm not sure what's going wrong in your second snippet, but in the first snippet you seem to be passing a StorageReference to Glide. Since Glide doesn't know anything about Firebase Storage, that won't work.
Instead, you should get a download URL from Firebase Storage, which is a regular HTTPS URL that provides public access to the data, and pass that to Glide to render in the view.
Something like:
reference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
// Got the download URL for 'users/me/profile.png'
Glide.with(ViewScenesSG.this)
.load(uri.toString())
.into(imageView);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle any errors
}
});
I have image view which loads image using Glide using download link. Code is given below :
How can I get the file name stored in fire base storage from the download url ?
Glide.with(ct)
.load(downloadurllink)
.centerCrop();
placeholder(R.drawable.common_icon_dark)
.into(holder.image);
I had the same problem and I used a Regular Expression to extract the file name from the download URL
%2..*%2F(.*?)\?alt
Eg: If your download URL is https://firebasestorage.googleapis.com/v0/b/art-track.appspot.com/o/images%2Fu1nffdGQ7QPLIMp7N11vSOYorUM2%2FCapture.JPG?alt=media&token=86081f67-9065-4a13-aa0b-14fab7d44bf3 , by using %2..*%2F(.*?)\?alt you can extract "Capture.JPG"
You can get filename easily using the name property.
Example:
val httpsReference = FirebaseStorage.getInstance().getReferenceFromUrl("https://firebasestorage.googleapis.com/v0/b/art-
track.appspot.com/o/images%2Fu1nffhbfdjsa%2FN11vSOYorUM2%2FImageName.JPG?
alt=media&token=86081f67-9065-4a13-aa0b-14fab7d44bf3")
Log.d(TAG, "filename: ${httpsReference.name}")
Android Example:
StorageReference storageReference = FirebaseStorage.getInstance().getReferenceFromUrl(urlImg);
String link = storageReference.getName();
Toast.makeText(EditAQuestionP1.this, link, Toast.LENGTH_SHORT).show();
If the URL is in this pattern:
https://firebasestorage.googleapis.com/v0/b/art-track.appspot.com/o/images%2Fu1nffhbfdjsa%2FN11vSOYorUM2%2FImageName.JPG?alt=media&token=86081f67-9065-4a13-aa0b-14fab7d44bf3
then this will work to split the URL into the pattern from 2F till 2F and it will remove the extension (.jpg or .png)
String url="https://firebasestorage.googleapis.com/v0/b/art-
track.appspot.com/o/images%2Fu1nffhbfdjsa%2FN11vSOYorUM2%2FImageName.JPG?
alt=media&token=86081f67-9065-4a13-aa0b-14fab7d44bf3";
print(url.split(RegExp(r'(%2F)..*(%2F)'))[1].split(".")[0]);
There are many options. Two of the most used ones are:
1. You can use File Metadata in Firebase Storage to get the file name from URL. Basically, you create a Firebase Data Reference and then add a file metadata listener, like this:
// Create a storage reference from our app
StorageReference storageRef = storage.getReference();
// Get reference to the file
StorageReference fileRef = storageRef.child("images/forest.jpg");
fileRef.getMetadata().addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
#Override
public void onSuccess(StorageMetadata storageMetadata) {
String filename = storageMetadata.getName();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Uh-oh, an error occurred!
}
});
This code was taken from the documentation which I advice you to check out: File Metadata
2. Another option is to store your URL with the name in Firebase Database. This has the advantage of avoiding unnecessary listeners. That means that you can get the name with a single value event listener without having to load all of the file metadata.
database.child("files").child("url")
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String name = dataSnapShot.getValue(String.class);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
}
It depends on your implementation on how you want to do it. Hope it helps :)
The easiest way is to use the reference method:
let storage = Storage.storage()
let yourFirestoreURL = "https://firebasestorage.googleapis.com/v0/b/art-track.appspot.com/o/images%2Fu1nffdGQ7QPLIMp7N11vSOYorUM2%2FCapture.JPG?alt=media&token=86081f67-9065-4a13-aa0b-14fab7d44bf3"
let storageRef = storage.reference(forURL: yourFirestoreURL)
print(storageRef.name)
For further details, see the google guide here: https://firebase.google.com/docs/storage/ios/create-reference
var storageReference =
firebase_storage.FirebaseStorage.instance.refFromURL(url);
String imgName = storageReference.name;
print(imgName);
If you want to delete a file having the url, you can do this:
final httpsReference = FirebaseStorage.instance.refFromURL(url);
await FirebaseStorageService.deleteFile(httpsReference.fullPath);
Solution for iOS!
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"%2F(.*?)\\?alt" options:NSRegularExpressionCaseInsensitive error:&error];
NSArray *matches = [regex matchesInString:photo_url options:0 range:NSMakeRange(0, [photo_url length])];
if (matches && matches.count > 0) {
NSString *substringForFirstMatch = [photo_url substringWithRange:[matches[0] rangeAtIndex:1]];
}
I am developing an android app that using firebase. My app looks like
App shows card that contains image.
I don't know how to manage image when app works in offline mode.
Could you give me suggestion to resolve it ?
First, use offline capabilities of Firebase by using .setPersistenceEnabled(true);
Use a Image Managing Cloud Server like Cloudinary to store all your images.
In your Firebase database, save the Url to the image as a String.
Use a Image Library like Picasso to get your image from the url.
This worked for me, hope it helps you.
Use Picasso or similar library for load image, show it and save in memory.
Use Firebase only for upload image to cloud and get link.
Example upload image:
StorageReference storageReference = FirebaseStorage.getInstance().getReference(app.packageName + ".webp");
UploadTask uploadTask = storageReference.putFile(Uri.fromFile(new File(app.icon)));
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
success = false;
countDown.countDown();
Log.e(TAG, "", e);
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Log.i(TAG, "onSuccess");
app.setPublicIconPath(taskSnapshot.getDownloadUrl().toString());
ref.child(app.getFirebaseKey()).child("icon").setValue(app.getFirebaseValueDataPart1().getIcon());
}
});