Время обновления метаданных хранилища FireBase возвращает 0? - PullRequest
0 голосов
/ 16 июня 2020

Я пытаюсь использовать Firebase для хранения и c синхронизации нескольких файлов CSV. Копии этих файлов CSV хранятся во внутреннем хранилище.

Чтобы обновить их локально, я просматриваю все элементы в сегменте хранилища Firebase, сравнивая время обновления между ними, а затем, если есть новая версия, загружаю ее.

Кажется, все работает отлично, кроме извлечения метаданных из Firebase, время последнего обновления файлов Firebase всегда возвращает ноль? Я нахожу это очень странным, потому что он может нормально загружать файл, а это означает, что не должно быть правила Firebase, блокирующего запрос на выборку метаданных или что-то еще. Время последнего обновления по умолчанию равно 0, если оно не добавлено вручную?

public void updateDataBase(View view){
    FirebaseStorage firebaseStorage = FireBaseStorage.getInstance();
    StorageReference reference = firebaseStorage.getReference().getRoot();

    final File rootpath = new File(getFilesDir(),"database");
    if(!rootpath.exists()){
        Log.i(TAG,"Folder Created: " + rootpath.mkdirs());
    }
    reference.listAll().addOnSuccessListener(new OnSuccessListener<ListResult>() {
        @Override
        public void onSuccess(ListResult listResult) {
            for(final StorageReference item : listResult.getItems()) {
                final File localFile = new File(rootpath, item.getName());
                final long[] onlineFileChangeDate = new long[1];
                item.getMetadata().addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
                    @Override
                    public void onSuccess(StorageMetadata storageMetadata) {
                        onlineFileChangeDate[0] = storageMetadata.getUpdatedTimeMillis();
                    }
                });
                Log.i("Settings","LastModified: " + localFile.lastModified());
                Log.i("Settings", "LastModified:" + onlineFileChangeDate[0]);
                if (localFile.lastModified() > onlineFileChangeDate[0]) {
                    Log.i(TAG, "File deleted " + localFile.delete());
                    item.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
                        @Override
                        public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
                            Toast.makeText(settings.this, "Downloaded: " + localFile, Toast.LENGTH_SHORT).show();

                        }
                    });

                }
            }
            Toast.makeText(settings.this, "Update Complete", Toast.LENGTH_SHORT).show();
        }
    }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    Log.e(TAG,"Firebase Update Error");
                }
            });
}

1 Ответ

1 голос
/ 16 июня 2020

Получение метаданных - это асинхронная операция, которая происходит в фоновом режиме, пока ваш основной код продолжается. Проще всего увидеть, что это означает, добавив несколько простых операторов журнала:

reference.listAll().addOnSuccessListener(new OnSuccessListener<ListResult>() {
    @Override
    public void onSuccess(ListResult listResult) {
        for(final StorageReference item : listResult.getItems()) {
            Log.i(TAG, "Before calling getMetadata()");

            item.getMetadata().addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
                @Override
                public void onSuccess(StorageMetadata storageMetadata) {
                    Log.i(TAG, "Got metadata");
                }
            });
            Log.i(TAG, "After calling getMetadata()");
        }
    }
})

При запуске этот код печатает:

Перед вызовом getMetadata ()

После вызова getMetadata ()

Получены метаданные

Вероятно, это не то, что вы ожидали, но он работает так, как задумано, и точно объясняет, почему ваш код не работает: к моменту запуска if (localFile.lastModified() > onlineFileChangeDate[0]) onlineFileChangeDate[0] = storageMetadata.getUpdatedTimeMillis() еще не установил для него значение.

Решение его (и любых других проблем с вызовами асинхронных методов) заключается в том, что код, которому нужны метаданные, должен находиться внутри onSuccess , который вызывается с этими метаданными, или вызываться оттуда.

Самое простое исправление:

reference.listAll().addOnSuccessListener(new OnSuccessListener<ListResult>() {
    @Override
    public void onSuccess(ListResult listResult) {
        for(final StorageReference item : listResult.getItems()) {
            final File localFile = new File(rootpath, item.getName());
            item.getMetadata().addOnSuccessListener(new OnSuccessListener<StorageMetadata>() {
                @Override
                public void onSuccess(StorageMetadata storageMetadata) {
                    if (localFile.lastModified() > storageMetadata.getUpdatedTimeMillis()) {
                        Log.i(TAG, "File deleted " + localFile.delete());
                        item.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
                            @Override
                            public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
                                Toast.makeText(settings.this, "Downloaded: " + localFile, Toast.LENGTH_SHORT).show();
                            }
                        });
                    }

                }
            });

        }
        Toast.makeText(settings.this, "Update Complete", Toast.LENGTH_SHORT).show();
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        Log.e(TAG,"Firebase Update Error");
    }
});

См. Также:

...