Невозможно хранить URL-адреса загрузки в Firebase Firestore - PullRequest
2 голосов
/ 02 августа 2020

Я пытаюсь сохранить изображения в хранилище Firebase, а затем загрузить URI этих изображений из хранилища Firebase, а затем снова загрузить эти URI в хранилище firebase, используя foreach l oop. Изображения успешно загружаются в хранилище firebase, но Uri только последнего изображения попадает в хранилище firestore, первые три не работают. Я создал ARRAY LIST OF BITMAPS, а затем использовал для него foreach l oop.

My Code

    private void UploadingImage() {

        if (bitmap != null && bitmap2 != null && bitmap3 != null && bitmap4 != null) {

            StorageTask arrayUpload;
            fuser = FirebaseAuth.getInstance().getCurrentUser();
            ProductName = Objects.requireNonNull(Product_Name_EditText.getText()).toString();
            CityName = Objects.requireNonNull(CityNameEditText.getText()).toString();

            // Bitmap[] bitmaps=new Bitmap[3];
            ArrayList<Bitmap> bitmapArrayList = new ArrayList<>();
            bitmapArrayList.add(bitmap);
            bitmapArrayList.add(bitmap2);
            bitmapArrayList.add(bitmap3);
            bitmapArrayList.add(bitmap4);

            Bitmap bitresized;

            for (Bitmap bitUpload : bitmapArrayList)
            {
                bitresized = Bitmap.createScaledBitmap(bitUpload, 800, 800, true);
                ByteArrayOutputStream baosArray = new ByteArrayOutputStream();
                bitresized.compress(Bitmap.CompressFormat.JPEG, 70, baosArray);
                byte[] uploadbaosarray = baosArray.toByteArray();
                i = i + 1;
                fileReference = storageReference.child(ProductName).child(i + ProductName + ".jpg");

                arrayUpload = fileReference.putBytes(uploadbaosarray);

                arrayUpload.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();
                        } else if (task.isSuccessful()) {
                            Toast.makeText(Upload_New_Product.this, "Uploaded Successfully", Toast.LENGTH_SHORT).show();
                            //mProgressBar.setVisibility(View.INVISIBLE);
                        }

                        return fileReference.getDownloadUrl();
                    }
                }).addOnCompleteListener(new OnCompleteListener<Uri>() {
                    @Override
                    public void onComplete(@NonNull Task<Uri> task) {
                        if (task.isSuccessful()) {
                            Uri downloadUri = task.getResult();
                            assert downloadUri != null;
                            String mUri = downloadUri.toString();

                            ProductName = Product_Name_EditText.getText().toString();
                            ProductRef = db.collection("Sellers").document(CityName).collection(Uid).document(ProductName);
                            HashMap<String, Object> map = new HashMap<>();
                            map.put("imageURL" + i, mUri);
                            //reference.updateChildren(map);
                            ProductRef.set(map, SetOptions.merge());

                        } else {
                            Toast.makeText(Upload_New_Product.this, "Failed!", Toast.LENGTH_SHORT).show();
                        }
                    }
                }).addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Toast.makeText(Upload_New_Product.this, e.getMessage(), Toast.LENGTH_SHORT).show();
                        //pd.dismiss();
                    }
                });

            }
        }
}

1 Ответ

1 голос
/ 02 августа 2020

Поскольку загрузка (и получение URL-адреса загрузки) являются асинхронными операциями, for l oop завершается почти сразу, и после этого все выгрузки происходят параллельно. Это означает, что к моменту запуска вашего map.put("imageURL" + i, mUri) переменная i будет его окончательным значением.

Чтобы код работал, вам нужно захватить переменную i для каждой итерации по l oop. Простой способ сделать это - переместить код, который загружает изображение и сохраняет его URL-адрес, в отдельную функцию и передавать значение i в вызов этой функции.

Что-то вроде:

public void uploadFileAtIndex(int i) {
    fileReference = storageReference.child(ProductName).child(i + ProductName + ".jpg");

    arrayUpload = fileReference.putBytes(uploadbaosarray);

    arrayUpload.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();
            } else if (task.isSuccessful()) {
                Toast.makeText(Upload_New_Product.this, "Uploaded Successfully", Toast.LENGTH_SHORT).show();
            }

            return fileReference.getDownloadUrl();
        }
    }).addOnCompleteListener(new OnCompleteListener<Uri>() {
        @Override
        public void onComplete(@NonNull Task<Uri> task) {
            if (task.isSuccessful()) {
                Uri downloadUri = task.getResult();
                assert downloadUri != null;
                String mUri = downloadUri.toString();

                ProductName = Product_Name_EditText.getText().toString();
                ProductRef = db.collection("Sellers").document(CityName).collection(Uid).document(ProductName);
                HashMap<String, Object> map = new HashMap<>();
                map.put("imageURL" + i, mUri);
                ProductRef.set(map, SetOptions.merge());
            } else {
                Toast.makeText(Upload_New_Product.this, "Failed!", Toast.LENGTH_SHORT).show();
            }
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Toast.makeText(Upload_New_Product.this, e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    });
}

А затем используйте его в l oop с:

for (Bitmap bitUpload : bitmapArrayList) {
    ...
    i = i + 1;
    uploadFileAtIndex(i);
}

Вам может потребоваться передать больше вашей переменной в uploadFileAtIndex, чем я сделал здесь, но его передача i, который решает вашу проблему прямо сейчас.

...