Cloud storage Denied Permission Android Studio - android

So I have added some security rules to my firebase storage when I use the simulation it works as expected but when I actually perform from my app it shows me this error
2021-04-09 16:43:00.322 17375-17375/com.margsapp.messenger E/StorageException: StorageException has occurred.
User does not have permission to access this object.
Code: -13021 HttpResult: 403
2021-04-09 16:43:00.323 17375-17375/com.margsapp.messenger E/StorageException: The server has terminated the upload session
java.io.IOException: The server has terminated the upload session
Caused by: java.io.IOException: { "error": { "code": 403, "message": "Permission denied. Could not perform this operation" }}
So I simplified the log cat
And this is my security rules
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read: if request.auth != null;
}
match/ProfileImages/{userId}{ //Am trying to upload an image to this directory.
allow read: if request.auth != null;
allow write: if request.auth != null && request.auth.uid == userId;
}
match/GroupImages{
allow read,write: if request.auth != null;
}
If the code which uploads image is necessary I will upload
If I done any mistake in rules please let me know the right way to do it.
EDIT: This is the code which uploads the image
storageReference = FirebaseStorage.getInstance().getReference("/ProfileImages/"+firebaseUser.getUid());
#Override
public void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == GALLERY_PICK && resultCode == RESULT_OK && data != null) {
imageUri = data.getData();
CropImage.activity(imageUri)
.setGuidelines(CropImageView.Guidelines.ON)
.setAspectRatio(1, 1)
.start(this);
}
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
CropImage.ActivityResult result = CropImage.getActivityResult(data);
if (resultCode == RESULT_OK) {
loadingBar.setTitle("Profile Image");
loadingBar.setMessage("Please wait, while we update your profile picture...");
loadingBar.show();
loadingBar.setCanceledOnTouchOutside(false);
assert result != null;
Uri resultUri = result.getUri();
StorageReference filepath = storageReference.child(System.currentTimeMillis()
+ "." + getFileExtension(resultUri));
uploadTask = filepath.putFile(resultUri);
uploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
#Override
public Task<Uri> then(#NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if (!task.isSuccessful()) {
throw task.getException();
}
return filepath.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()) {
Toast.makeText(edit_profile.this, "Image has been stored in our servers", Toast.LENGTH_SHORT).show();
Uri downloadUri = task.getResult();
assert downloadUri != null;
String mUri = downloadUri.toString();
reference = FirebaseDatabase.getInstance().getReference("Users").child(firebaseUser.getUid());
HashMap<String, Object> map = new HashMap<>();
map.put("imageURL", mUri);
reference.updateChildren(map);
loadingBar.dismiss();
}
}
});
} else {
Toast.makeText(this, "Profile Picture updation is cancelled", Toast.LENGTH_SHORT).show();
loadingBar.dismiss();
}
}
}
private String getFileExtension(Uri uri){
ContentResolver contentResolver = edit_profile.this.getContentResolver();
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
return mimeTypeMap.getExtensionFromMimeType(contentResolver.getType(uri));
}

To solve your problem you need to match all paths within:
ProfileImages -> userId
In your Storage bucket. So your rules should look like this:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read: if request.auth != null;
}
match /ProfileImages/{userId} {
match /{allPaths=**} {
allow read: if request.auth != null;
allow write: if request.auth != null && request.auth.uid == userId;
}
}
}
}

Related

Cannot resolve symbol - Bitmap image compress and upload to Firebase

I'm trying to select an image, compress it and then upload it to the firebase Storage. I'm trying the following code but getting an error that Cannot resolve symbol 'data2'.
This is my activity:
private void openFileChooserOne() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent, PICK_IMAGE_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK &&
data != null && data.getData() != null) {
mImageUri = data.getData();
Picasso.get().load(mImageUri).into(mImageView);
}
}
private void uploadFile() {
FirebaseUser user = mAuth.getCurrentUser();
String userID = user.getUid();
if (mImageUri != null && mImageMedicalUri != null) {
StorageReference fileReference = mStorageRef.child(userID).child("image.jpg");
try {
Bitmap bmp = MediaStore.Images.Media.getBitmap(getContentResolver(), mImageUri);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 25, baos);
byte[] data2 = baos.toByteArray();
} catch (IOException ioEx) {
ioEx.printStackTrace()
}
mUploadTask = fileReference.putBytes(data2) //Getting error here
.addOnSuccessListener(new OnSuccessListener < UploadTask.TaskSnapshot > () {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
//
});
}
})
}
I'm new in Java and trying to understand the problem. Will very much appreciate your help to know what I'm doing wrong here.
When you are using the following line of code:
mUploadTask = fileReference.putBytes(data2)
Your data2 variable is outside the scope where it was declared. To solve this, you should either move this line inside the try-catch block or make the data2 variable as a global variable.

Unable to save image to Firebase

In my android app i am using Firebase Storage to save images i have set security rules to null then too i am not able to upload images and getting error.
Below are my error ,security rules and android code.Please let me know what i did wrong in code.
Logcat error : StorageException has occurred.
User does not have permission to access this object.
Code: -13021 HttpResult: 403
Security rules:
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth == null;
}
}
}
Java code:
galleryFab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
if(ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(SetAvatar.this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},1);
}
else{
Intent i = new Intent(Intent.ACTION_PICK);
i.setType("image/*");
startActivityForResult(i,GALLERY_INTENT);
}
}
}
});
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent
data) {
if(requestCode == GALLERY_INTENT && resultCode == RESULT_OK){
uri = data.getData();
cv.setImageURI(uri);
final StorageReference filepath = sRef.child("Profile
Images").child(uri.getLastPathSegment());
UploadTask uploadTask = filepath.putFile(uri);
uploadTask.addOnSuccessListener(new
OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(SetAvatar.this, "Upload
successful",Toast.LENGTH_SHORT).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(SetAvatar.this, "Upload Failed -> " + e,
Toast.LENGTH_SHORT).show();
}
});
}
}
Thanks
change your security rules to:
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write;
}
}
}
But this will make your Bucket to be modified by anyone and I don't recommend it. However, you may use it for testing purposes.

Retrieving image from Mediastore is null

I'm trying to save an image from the camera of the phone and then retrieve it to save it on firebase storage.
I tryed a lot of ways of doing it, but I always get a null when I retrieve it.
Here it is how I make the picture with the camera:
private void camera() {
if (ActivityCompat.checkSelfPermission(MainChatActivity.this,
Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
Intent i = new Intent();
i.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(i, PHOTO_CAMERA_IMAGE);
}
}
Here I save it on the phone:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case PICK_IMAGE:
if (data != null)
uploadImage(data.getData());
break;
case PHOTO_CAMERA_IMAGE:
if (resultCode == RESULT_OK) {
if (data != null) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
// Continue only if the File was successfully created
if (photoFile != null) {
photoURI = FileProvider.getUriForFile(this,
"borealos.com.chat.fileprovider",
photoFile);
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, photoURI));
takePictureIntent.putExtra("foto", photoURI);
Uri uri = (Uri) takePictureIntent.getExtras().get(MediaStore.EXTRA_OUTPUT);
uploadImage(photoURI);
// startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
} catch (IOException ex) {
// Error occurred while creating the Fil
}
}
}
}
break;
}}
And here I retrieve it for uploading on firebase:
private void uploadImage( final Uri filePath) {
Uri filePath2=filePath;
final String s;
if (filePath != null) {
final ProgressDialog progressDialog = new ProgressDialog(this);
progressDialog.setTitle("Uploading...");
progressDialog.show();
s = UUID.randomUUID().toString();
ref = storageReference.child("images/" + s);
ref.putFile(filePath)
.addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<UploadTask.TaskSnapshot> task) {
if (task.isSuccessful()) {
progressDialog.dismiss();
sendImage(filePath, task.getResult().getDownloadUrl().toString());
}
}
});
}
}
Thanks for the help in advice

Uploading Image to firebase storage doesnt work with some images when i added progessDialog

I am trying to build a replace profile picture functionality in my code using the codes below.It works fine sometimes.Other times, nothing happens after i select the picture from my gallery(Some images).It appears the select image from gallery activity just crashes after i select the image to upload and the application just terminates in logcat without any error.It used to work fine before i added the progress dialog
private void postImage() {
String path = "userProfiles/" + UUID.randomUUID() + ".jpeg";
StorageReference userProfilesRef = storage.getReference(path);
userProfilesRef.putFile(resultUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
downloadUrls = taskSnapshot.getDownloadUrl().toString();
Toast.makeText(getApplicationContext(), "File Uploaded ", Toast.LENGTH_LONG).show();
mProgressDialog.dismiss();
final String id = firebaseAuth.getCurrentUser().getUid();
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.child("Male").hasChild(id)){
databaseReference.child("Male").child(id).child("downloadUrl").setValue(downloadUrls);
databaseReference1.child("Male").child(key).child("downloadUrl").setValue(downloadUrls);
}
else {
databaseReference.child("Female").child(id).child("downloadUrl").setValue(downloadUrls);
databaseReference1.child("Female").child(key).child("downloadUrl").setValue(downloadUrls);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Toast.makeText(getApplicationContext(), " Uploaded ", Toast.LENGTH_LONG).show();
}
});
}
});
/* userProfilesRef.putFile(filePath).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getApplicationContext(), " Upload Failed, Please try again ", Toast.LENGTH_LONG).show();
//progressDialog.dismiss();
}
});*/
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
filePath = data.getData();
CropImage.activity(filePath)
.setGuidelines(CropImageView.Guidelines.ON)
.setAspectRatio(1, 1)
.start(this);
}
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
CropImage.ActivityResult result = CropImage.getActivityResult(data);
if (resultCode == RESULT_OK) {
mProgressDialog.setMessage("Uploading Please Wait...");
mProgressDialog.show();
resultUri = result.getUri();
postImage();
image.setImageURI(resultUri);
} else if (resultCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
Exception error = result.getError();
}
}
}
try to add
if(mProgressDialog != null)
mProgressDialog.dismiss();
if there is no error so you miss something at your dialog declaration

data.getData() returns null in OnActvityResult while taking /Selecting Pictures from Camera and Gallery

I am developing an android app, which has a profile fragment where users can upload profile picture via taking picture or selecting from gallery. For now, everything is working fine via Activity.RESULT_OK. But the problem is the onActivityResult data.getData() that is returning nothing. I have made researches on this issue to no avail.
These are the two methods contained in my editprofile fragment.
private void setGalleryBtn() {
if (PermissionHandler.checkPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)) {
AppHelper.LogCat("Read data permission already granted.");
new PickerBuilder(getActivity(), PickerBuilder.SELECT_FROM_GALLERY)
.setOnImageReceivedListener(imageUri -> {
Intent data = new Intent();
data.setData(imageUri);
AppHelper.LogCat("new image SELECT_FROM_GALLERY" + imageUri);
mEditProfilePresenter.onActivityResult(this, AppConst.SELECT_PROFILE_PICTURE, RESULT_OK, data);
})
.setImageName(getActivity().getString(R.string.app_name))
.setImageFolderName(getActivity().getString(R.string.app_name))
.setCropScreenColor(R.color.colorPrimary)
.withTimeStamp(false)
.setOnPermissionRefusedListener(() -> {
PermissionHandler.requestPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE);
})
.start();
} else {
AppHelper.LogCat("Please request Read data permission.");
PermissionHandler.requestPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE);
}
}
private void setCameraBtn() {
if (PermissionHandler.checkPermission(getActivity(), Manifest.permission.CAMERA)) {
AppHelper.LogCat("camera permission already granted.");
new PickerBuilder(getActivity(), PickerBuilder.SELECT_FROM_CAMERA)
.setOnImageReceivedListener(imageUri -> {
AppHelper.LogCat("new image SELECT_FROM_CAMERA " + imageUri);
Intent data = new Intent();
data.setData(imageUri);
mEditProfilePresenter.onActivityResult(this, AppConst.SELECT_PROFILE_CAMERA, RESULT_OK, data);
})
.setImageName(getActivity().getString(R.string.app_name))
.setImageFolderName(getActivity().getString(R.string.app_name))
.setCropScreenColor(R.color.colorPrimary)
.withTimeStamp(false)
.setOnPermissionRefusedListener(() -> {
PermissionHandler.requestPermission(getActivity(), Manifest.permission.CAMERA);
})
.start();
} else {
AppHelper.LogCat("Please request camera permission.");
PermissionHandler.requestPermission(getActivity(), Manifest.permission.CAMERA);
}
}
This is my EditProfilePresenter.onActivityResult method.
public void onActivityResult(Edit_profile_fragment myEdit_profile_fragment, int requestCode, int resultCode, Intent data) {
String imagePath = null;
if (resultCode == Activity.RESULT_OK) {
if (PermissionHandler.checkPermission(myEdit_profile_fragment.getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE)) {
AppHelper.LogCat("Read contact data permission already granted.");
switch (requestCode) {
case AppConst.SELECT_PROFILE_PICTURE:
imagePath = FilesManager.getPath(myEdit_profile_fragment.getActivity(), data.getData());
break;
case AppConst.SELECT_PROFILE_CAMERA:
if (data.getData() != null) {
imagePath = FilesManager.getPath(myEdit_profile_fragment.getActivity(), data.getData());
} else {
try {
String[] projection = new String[]{MediaStore.Images.ImageColumns._ID, MediaStore.Images.ImageColumns.DATA, MediaStore
.Images.ImageColumns.BUCKET_DISPLAY_NAME, MediaStore.Images.ImageColumns.DATE_TAKEN, MediaStore.Images
.ImageColumns.MIME_TYPE};
final Cursor cursor = myEdit_profile_fragment.getActivity().getContentResolver()
.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null, null, MediaStore.Images.ImageColumns
.DATE_TAKEN + " DESC");
if (cursor != null && cursor.moveToFirst()) {
String imageLocation = cursor.getString(1);
cursor.close();
File imageFile = new File(imageLocation);
if (imageFile.exists()) {
imagePath = imageFile.getPath();
}
}
} catch (Exception e) {
AppHelper.LogCat("error" + e);
}
}
break;
}
if (imagePath != null) {
EventBus.getDefault().post(new Pusher(AppConst.EVENT_BUS_IMAGE_PROFILE_PATH, imagePath));
} else {
AppHelper.LogCat("imagePath is null");
}
} else {
AppHelper.LogCat("Please request Read contact data permission.");
PermissionHandler.requestPermission(myEdit_profile_fragment.getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE);
}
}
}
Please what am I getting wrong?
You can Try this
if (requestCode == REQUEST_FROM_CAMERA && resultCode == RESULT_OK)
{
Bundle extras2 = data.getExtras();
if (extras2 != null) {
// do your stuff here
}
else {
// handle this case as well if data.getExtras() is null
Uri selectedImage = data.getData();
}
}
Hope it helps you

Categories

Resources