简体   繁体   中英

Firebase Storage - Prevent Overwriting of Files

I am allowing users to take pictures and store them to Firebase. Below is my code that contains the intent to load the camera application, save the image, and then upload to the Firebase storage. The problem I am having is each subsequent upload to the Firebase Storage is overriding the previous upload, meaning I have 1 file in storage that keeps being overridden. I want to keep adding multiple files:

private void createAlertDialog() {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(R.string.add_image_dialog_title);
    builder.setItems(new CharSequence[]
                    {getResources().getString(R.string.add_image_web), getResources().getString(R.string.add_image_camera), getResources().getString(R.string.add_image_gallery)},
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    // The 'which' argument contains the index position
                    // of the selected item
                    switch (which) {
                        case 0:
                            Intent toImageSearch = new Intent(CreateActivity.this, NewImageActivity.class);
                            startActivityForResult(toImageSearch, USE_WEB);
                            break;
                        case 1:
                            Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                            if (takePictureIntent.resolveActivity(getApplication().getPackageManager()) != null) {
                                startActivityForResult(takePictureIntent, TAKE_PICTURE);
                            } else {
                                Toast.makeText(getApplicationContext(), getResources().getString(R.string.camera_error), Toast.LENGTH_LONG).show();
                            }
                            break;
                        case 2:
                            Toast.makeText(getApplicationContext(), "clicked 2", Toast.LENGTH_LONG).show();
                            break;
                        case 3:
                            Toast.makeText(getApplicationContext(), "clicked 3", Toast.LENGTH_LONG).show();
                            break;
                    }
                }
            }

    );
    builder.create().

            show();
}

OnActivityResult()

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case USE_WEB:
            if (resultCode == CreateActivity.RESULT_OK) {
                resultImageURL = data.getStringExtra("result");
                mAddImageButton.setVisibility(View.INVISIBLE);
                Picasso.with(getApplicationContext())
                        .load(resultImageURL)
                        .into(mImagePreview);
            }
            if (resultCode == CreateActivity.RESULT_CANCELED) {
                //Write your code if there's no result
            }

        case TAKE_PICTURE:
            if (resultCode == CreateActivity.RESULT_OK) {
                Bundle extras = data.getExtras();
                Bitmap imageBitmap = (Bitmap) extras.get("data");
                mImagePreview.setImageBitmap(imageBitmap);
                encodeBitmapAndSaveToFirebase(imageBitmap);
            }
    }
}

Save to Firebase:

 private void encodeBitmapAndSaveToFirebase(Bitmap bitmap) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    byte[] data = baos.toByteArray();

    UploadTask uploadTask = mPollImageStorage.putBytes(data);
    uploadTask.addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception exception) {
            Toast.makeText(getApplicationContext(), "Error Loading Photo", Toast.LENGTH_LONG).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.
            Uri downloadUrl = taskSnapshot.getDownloadUrl();
            mAddImageButton.setVisibility(View.INVISIBLE);
            resultImageURL = downloadUrl.toString();
            Picasso.with(getApplicationContext())
                    .load(resultImageURL)
                    .into(mImagePreview);
        }
    });

}

You need to use a separate location or separate file name for each upload.

You can create a custom location like this:

 FirebaseStorage storage = FirebaseStorage.getInstance();
            StorageReference storageRef = storage.getReferenceFromUrl("gs://myfirebaseproject.appspot.com");
            StorageReference fileRef =
                    storageRef.child(channelId)
                    .child(String.valueOf(message.getSender()))
                    .child(String.valueOf(message.getTimestamp()));

            UploadTask uploadTask = fileRef.putFile(message.getAttachmentUri());
            uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                @Override
                public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                    sendMessage(channelId, message.getMessageText(), taskSnapshot.getStorage().toString(), message.getAttachmentType(), callback);
                }
            });
            uploadTask.addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    callback.onError(e.toString());
                }
            }); 

You can see we are adding custom locations to our base storage reference so that we don't overwrite existing items.

The location that you store your image is determined by what mPollImageStorage is referencing. If mPollingStorage always references the same place, ie, in your onCreate you do something like:

StorageReference mPollingStorage = storageRef.child("polling.jpg");

Then it will keep overriding camerapic.jpg . If you don't want to override it, you could set the image name to something like the time the image was taken or generate a UUID as per this stackoverflow post : Store files with unique/random names

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM