I want to upload the image captured from camera to firebase Storage. I know how to store the image once I get the Uri format of image but I am getting Bitmap from camera activity. So I need to know how to do that?
click_picture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent,2);
}
});
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Bitmap bitmap = (Bitmap)data.getExtras().get("data");
image.setImageBitmap(bitmap);
}
public String getFileExtendsion(Uri uri){
ContentResolver contentResolver = getActivity().getContentResolver();
MimeTypeMap mime = MimeTypeMap.getSingleton();
return mime.getExtensionFromMimeType(contentResolver.getType(uri));
}
public void uploadFile(){
if(mImageUri!=null){
final StorageReference fileReference = mStorageRef.child("ProfilePicture"+"."+getFileExtendsion(mImageUri));
fileReference.putFile(mImageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
fileReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
///store the uri
}
});
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.i("Fail",e.getMessage());
}
});
}
}
I have function uploadFile() to store the Uri of image to firebase storage and then get the url of the image to store it in firebase realtime database. But do I need to convert the bitmap to Uri? If yes, how? The code I found isn't working and if there's any other way please tell me!Thanks for your time :)
If you're getting a bitmap from the camera, see the first example in the Firebase documentation showing how upload from data that you have in memory, which conveniently starts with a Bitmap.
From there:
// Get the data from an ImageView as bytes
imageView.setDrawingCacheEnabled(true);
imageView.buildDrawingCache();
Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] data = baos.toByteArray();
UploadTask uploadTask = mountainsRef.putBytes(data);
Related
My firestore reference:
storageRef = FirebaseStorage.getInstance().getReference().child("/folder/photo.jpg");
I use a camera intent to get an image:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
}
On activity result I get the image and upload it:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] data = baos.toByteArray();
ByteArrayInputStream bs = new ByteArrayInputStream(data);
UploadTask uploadTask = storageRef.putStream(bs);
uploadTask.addOnSuccessListener(taskSnapshot -> {
new L().info(storageRef.getDownloadUrl()+"");
new AlertUtil().showCustomAlert(this,"done");
});
}
}
However the storageRef.getDownloadUrl() returns this:
com.google.android.gms.tasks.zzu#64b8bf6
The code is from the documentation:
[https://firebase.google.com/docs/storage/android/upload-files][1]
What am I missing here? How do I get the download URL
Uri selectedImageUri = data.getData();
StorageReference photoRef = mSRreference.child(selectedImageUri.toString());
photoRef.putFile(selectedImageUri).addOnSuccessListener(new
OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot){
// your download uri - taskSnapshot.getDownloadUrl()
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
}
});
I tried the Task<Uri> urlTask = uploadTask.continueWithTask... code from the documentation and it did not work.
So I tried uploading the file then getting the image url which seemed like the simplest way to go and it worked:
UploadTask uploadTask = storageRef.putStream(bs);
uploadTask.addOnSuccessListener(taskSnapshot -> {
storageRef.getDownloadUrl().addOnCompleteListener(task ->
new L().info("url" + task.getResult()));
});
I would like to point out that the documentation is not very good. I am using java 1.8 hence the shorter lamba syntax. Add
compileOptions {
targetCompatibility 1.8
sourceCompatibility 1.8
}
to your app build.gradle to do so.
How to upload the image without "upload" button and to use that new image automatically as default user picture? How can I implement this in my code.
mAuth = FirebaseAuth.getInstance();
circlePic = findViewById(R.id.circleImageView);
FirebaseUser user = mAuth.getCurrentUser();
if (user != null) {
Glide.with(this)
.load(user.getPhotoUrl())
.into(circlePic);
public void Profile(View view) {
Intent cpicview = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(cpicview, 1);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageRIntent) {
super.onActivityResult(requestCode, resultCode, imageRIntent);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK)
mProfileUri = imageRIntent.getData();
Uri selectedImage = imageRIntent.getData();
this.circlePic.setImageURI(selectedImage);
first add click listener to your imageview that will open activity to choose an image
profileImage.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Profile Image"), REQUEST_CODE);
}
});
then implement onActivityResult that will be executed when image is selected
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (requestCode == REQUEST_CODE) {
InputStream inputStream = context.getContentResolver().openInputStream(data.getData());
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
uploadImage(bitmap);
}
}
this is the method to upload Bitmap
private void uploadImage(Bitmap bitmap)
{
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageRef = storage.getReferenceFromUrl("Your url for storage");
StorageReference mountainImagesRef = storageRef.child("images/" + chat_id + Utils.getCurrentTimeStamp() + ".jpg");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 20, baos);
byte[] data = baos.toByteArray();
UploadTask uploadTask = mountainImagesRef.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) {
Uri downloadUrl = taskSnapshot.getDownloadUrl();
Log.d(downloadUrl);
}
});
}
and don't forget to declare REQUEST_CODE in your class
public static final int REQUEST_CODE = 1;
and maybe you will need to add this line in your xml for your profile image view
android:clickable="true"
I'm building an Android app and am currently integrating Google Firebase. I've already set up a database. Since my app will download sensitive images via Google Firebase storage, access to these images must only be allowed for authorized users. In the Firebase database I manually added the URLs of the images from the storage (I would have preferred to do it automatically, but I don't know how).
What is the best way to give different users access to different graphics in the Firebase storage?
Thanks!
Edit: Iam allready read that: Google Firebase but renaming images in difficult to guess names, doesn't seem to be the safest solution
Does the user upload the image or you through the app?
I can suggest this if so:
Have a private image button.
in onCreate()
imageButton = (ImageButton) findViewById(R.id.ibImageSelect);
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent galleryIntent = new Intent(Intent.ACTION_GET_CONTENT);
galleryIntent.setType("image/*");
startActivityForResult(galleryIntent, Gallery_Request);
}
});
outside a method body:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == Gallery_Request && resultCode == RESULT_OK) {
imageUri = data.getData();
imageButton.setImageURI(imageUri);
}
}
On your button click
StorageReference upload = storageReference.child("what you want");
Bitmap bmp = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] data = baos.toByteArray();
UploadTask filePath = upload.child(imageUri.getLastPathSegment()).putBytes(data);
filePath.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
filePath.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
DatabaseReference newPost = mref.push(); //this generates a random unique key
replace with your own if you want, since you already got your own structure
newPost.child("image").setValue(imageUri.getLastPathSegment());
//set image name so can use this to download the image
}
});
you could have a "status" child in each node of the data, then when downloading the images you loop through all the nodes, check if the status is what you want to to be. Then get the image download key.
for downloading images:
loop through the nodes and children, get the img url,
String ref = "image folder in firebase storage/" + imgurl;
storageRef.child(ref).getBytes(Long.MAX_VALUE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
#Override
public void onSuccess(byte[] bytes) {
// Use the bytes to display the image
final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
ImageView iv = (ImageView) findViewByID(R.id...);
iv.setImageBitmap(bitmap);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Log.i("error", exception.getMessage());
}
});
I created a simple application which crop the image . Now I want to save this image to the Fire base .
photo.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Intent imageDownload = new
Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Intent imageDownload=new Intent();
imageDownload.setAction(Intent.ACTION_GET_CONTENT);
imageDownload.setType("image/*");
imageDownload.putExtra("crop", "true");
imageDownload.putExtra("aspectX", 1);
imageDownload.putExtra("aspectY", 1);
imageDownload.putExtra("outputX", 200);
imageDownload.putExtra("outputY", 200);
imageDownload.putExtra("return-data", true);
startActivityForResult(imageDownload, GALLERY_REQUEST_CODE);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent
data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == GALLERY_REQUEST_CODE && resultCode == RESULT_OK &&
data != null) {
Bundle extras = data.getExtras();
image = extras.getParcelable("data");
photo.setImageBitmap(image);
}
}
How to save this image to the Firebase . I tried many tutorial but could not succeed . Please verify with simple code .
you must first add the dependencies for Firebase Storage to your build.gradle file:
compile 'com.google.firebase:firebase-storage:10.0.1'
compile 'com.google.firebase:firebase-auth:10.0.1'
then create an instance of FirebaseStorage:
FirebaseStorage storage = FirebaseStorage.getInstance();
To upload a file to Firebase Storage, you first create a reference to the full path of the file, including the file name.
// Create a storage reference from our app
StorageReference storageRef = storage.getReferenceFromUrl("gs://<your-bucket-name>");
// Create a reference to "mountains.jpg"
StorageReference mountainsRef = storageRef.child("mountains.jpg");
// Create a reference to 'images/mountains.jpg'
StorageReference mountainImagesRef = storageRef.child("images/mountains.jpg");
// While the file names are the same, the references point to different files
mountainsRef.getName().equals(mountainImagesRef.getName()); // true
mountainsRef.getPath().equals(mountainImagesRef.getPath()); // false
Once you've created an appropriate reference, you then call the putBytes(), putFile(), or putStream() method to upload the file to Firebase Storage.
The putBytes() method is the simplest way to upload a file to Firebase Storage. putBytes() takes a byte[] and returns an UploadTask that you can use to manage and monitor the status of the upload.
// Get the data from an ImageView as bytes
imageView.setDrawingCacheEnabled(true);
imageView.buildDrawingCache();
Bitmap bitmap = imageView.getDrawingCache();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] data = baos.toByteArray();
UploadTask uploadTask = mountainsRef.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.
Uri downloadUrl = taskSnapshot.getDownloadUrl();
}
});
Firebase does not support binary data, so you need to convert the image data to base64 or use Firebase Storage
Method 1 ( Recommended )
sref = FirebaseStorage.getInstance().getReference(); // please go to above link and setup firebase storage for android
public void uploadFile(Uri imagUri) {
if (imagUri != null) {
final StorageReference imageRef = sref.child("android/media") // folder path in firebase storage
.child(imagUri.getLastPathSegment());
photoRef.putFile(imagUri)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot snapshot) {
// Get the download URL
Uri downloadUri = snapshot.getMetadata().getDownloadUrl();
// use this download url with imageview for viewing & store this linke to firebase message data
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// show message on failure may be network/disk ?
}
});
}
}
Method 2
for small images we can still go with this solution, there is firebase field value
limitations(1MB field value)
check official doc for details
public void getImageData(Bitmap bmp) {
ByteArrayOutputStream bao = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, bao); // bmp is bitmap from user image file
bmp.recycle();
byte[] byteArray = bao.toByteArray();
String imageB64 = Base64.encodeToString(byteArray, Base64.URL_SAFE);
// store & retrieve this string which is URL safe(can be used to store in FBDB) to firebase
// Use either Realtime Database or Firestore
}
"firebase-storage 16.0.1"
task.getDowloadUrl() not defined. You can use this i check , working perfectly.
private void firebaseUploadBitmap(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] data = stream.toByteArray();
StorageReference imageStorage = storage.getReference();
StorageReference imageRef = imageStorage.child("images/" + "imageName");
Task<Uri> urlTask = imageRef.putBytes(data).continueWithTask(task -> {
if (!task.isSuccessful()) {
throw task.getException();
}
// Continue with the task to get the download URL
return imageRef.getDownloadUrl();
}).addOnCompleteListener(task -> {
if (task.isSuccessful()) {
Uri downloadUri = task.getResult();
String uri = downloadUri.toString();
sendMessageWithFile(uri);
} else {
// Handle failures
// ...
}
progressBar.setVisibility(View.GONE);
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE && resultCode == Activity.RESULT_OK) {
// Bitmap imageBitmap = data.getData() ;
Bitmap photo = (Bitmap) data.getExtras().get("data");
if (photo != null)
firebaseUploadBitmap(photo);
} else if (requestCode == SELECT_IMAGE && resultCode == Activity.RESULT_OK) {
Uri uri = data.getData();
if (uri != null)
firebaseUploadImage(uri);
}
}
i try to upload to firebase a picture and when i upload its show me that the size of the file is 0 bytes and dont show the content picture
everything seems fine, then whay its happen???
StorageReference storageRef = storage.getReferenceFromUrl("gs://<your-bucket-name>");
if (inputStream!=null) {
String pic = "BathroomImage" + +rand.nextInt(1000) + ".jpg";
mountainsRef = storageRef.child(pic);
uploadTask = mountainsRef.putStream(inputStream);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.d("this is the faiure:","hey im here");
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
taskSnapshot.getMetadata();
Uri downloadUri = taskSnapshot.getDownloadUrl();
bitmap.recycle();
bitmap=null;
System.gc();
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
here i upload the picture from the data to inputsream.
void TakePickphoto(){
Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); // Create intent to Open Image applications like Gallery, Google Photos
startActivityForResult( galleryIntent, RESULT_LOAD_IMAGE);// Start the Intent
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_IMAGE && resultCode ==getActivity().RESULT_OK && null != data) {
selectedImage = data.getData(); // Get the URI Image from data
handler= new Handler();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
inputStream = context.getContentResolver().openInputStream(data.getData());
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize =4;
bitmap = BitmapFactory.decodeStream(inputStream, new Rect(40,40,40,40),options);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
#Override
public void run() {
ImageView imageView;
imageView = (ImageView) view.findViewById(R.id.imageView2);
imageView.setImageBitmap(bitmap);
}
});
}
};
new Thread(runnable).start();
}
}
}
please help, everything look fine to me.
** This will not save the image in full resolution **
To save a picture in full resolution, research how to do that when you start the TakePictureIntent.
I had the same error and solved it by setting up my picture taking and uploading like this:
//takes the picture
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getActivity().getPackageManager()) != null) {
startActivityForResult(takePictureIntent, 1);
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
//saves the pic locally
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
byte[] dataBAOS = baos.toByteArray();
/***************** UPLOADS THE PIC TO FIREBASE*****************/
// Points to the root reference
StorageReference storageRef = FirebaseStorage.getInstance().getReferenceFromUrl("your-root-storage-ref");
StorageReference imagesRef = storageRef.child("image");
UploadTask uploadTask = imagesRef.putBytes(dataBAOS);
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.
Uri downloadUrl = taskSnapshot.getDownloadUrl();
}
});
}
}
This way it will compress and save your image in your Firebase Storage with this file struct:
root -> image
You can pass the InputStream directly from the Uri to the putStream method. You may want to resize the image yourself before uploading it, which would require a bit more work, but this way uses very little memory on the client side.
if (requestCode == IMAGE_PICKER_SELECT && resultCode == Activity.RESULT_OK) {
Uri imageUri = data.getData();
try {
ContentResolver contentResolver = getActivity().getContentResolver();
StorageMetadata storageMetadata = new StorageMetadata.Builder()
.setContentType(contentResolver.getType(imageUri))
.build();
FirebaseStorage.getInstance().getReference()
.child("users")
.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.child(UUID.randomUUID().toString())
.putStream(contentResolver.openInputStream(imageUri), storageMetadata)
.addOnSuccessListener(getActivity(), new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot task) {
Uri downloadUrl = task.getDownloadUrl();
Toast.makeText(getActivity(), R.string.image_successfully_uploaded, Toast.LENGTH_LONG).show();
}
})
.addOnFailureListener(getActivity(), new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getActivity(), R.string.error_uploading_image, Toast.LENGTH_LONG).show();
}
});
} catch (IOException e) {
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}