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());
}
});
Related
I'm trying to take a photo and upload it to the server, but I'm outputting a thumbnail photo. How can I get it in Full-Size?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setTitle("Set");
SharedPreferences sharedPreferences = getSharedPreferences("Userınfo",0);
email = sharedPreferences.getString("deneme",email);
setContentView(R.layout.tamir_islem);
qrcode=findViewById(R.id.qrcode);
arizaPhoto = findViewById(R.id.arizafoto);
imageShow = findViewById(R.id.arizafotoshow);
arizaPhoto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent1 = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if(intent1.resolveActivity(getPackageManager()) != null){
startActivityForResult(intent1,CAMERA_ACTION_CODE);
}else{
Toast.makeText(tester.this,"There is no app that support this action",Toast.LENGTH_SHORT).show();
}
}
});
I use this code for taking pictures and string operations.
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data){
super.onActivityResult(requestCode,resultCode,data);
if(requestCode == CAMERA_ACTION_CODE && resultCode == RESULT_OK && data != null) {
Bundle bundle = data.getExtras();
finalPhoto = (Bitmap) bundle.get("data");
System.out.println(bundle);
System.out.println(finalPhoto);
imageShow.setImageBitmap(finalPhoto);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
finalPhoto.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream);
byte[] byteArray = byteArrayOutputStream.toByteArray();
System.out.println(Arrays.toString(byteArray));
encoded = Base64.encodeToString(byteArray, Base64.DEFAULT);
}
I use this to send..
#Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String,String> param = new HashMap<>();
param.put("encoded",encoded);
return param;
}
Thank you for your attention. :)
From the docs at MediaStore
The caller may pass an extra EXTRA_OUTPUT to control where this image will be written. If the EXTRA_OUTPUT is not present, then a small sized image is returned as a Bitmap object in the extra field. This is useful for applications that only need a small image.
To retrieve a full image you need to write it to a file. If you don't want to save this image then create a temporary file and delete it after sending it to the server.
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);
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.
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);
}
}
Does Google's Firebase support video storage ? Am planning to upload video and want to download on-demand. I started with Firebase. Are there any other APIs or services that give a similar functionality ?
Of course you can upload video or any files on firebase.
btnupload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent myIntent = new Intent(Intent.ACTION_GET_CONTENT);
myIntent.setType("*/*");
startActivityForResult(Intent.createChooser(myIntent,"Select File:-"),101);
}
});
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if(resultCode==RESULT_CANCELED)
{
// action cancelled
}
if(resultCode==RESULT_OK)
{
// Create a storage reference from our app
StorageReference storageRef = storage.getReferenceFromUrl("gs://<<Your App Bucket Address>>");
Uri uri = data.getData();
StorageReference riversRef = storageRef.child("files/"+uri.getLastPathSegment());
UploadTask uploadTask = riversRef.putFile(uri);
// Register observers to listen for when the download is done or if it fails
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle unsuccessful uploads
Toast.makeText(MainActivity.this, "Upload Failed", Toast.LENGTH_SHORT).show();
}
}).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.
Toast.makeText(MainActivity.this, "Upload Success", Toast.LENGTH_SHORT).show();
}
});
}
}
Firebase has a Firebase Storage offering that allows you to store any arbitrary files.
It doesn't offer any video-specific features or functionality, but it will work if you simply want to have a place to store and retrieve your video files.