FireBase存储元数据更新时间返回0? [英] FireBase Storage MetaData-Updated Time returning 0?

查看:79
本文介绍了FireBase存储元数据更新时间返回0?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Firebase存储和同步多个CSV文件.这些CSV文件的副本存储在内部存储器中.

I am attempting to use Firebase to store and sync several CSV files. Copies of these CSV files are stored in internal storage.

要在本地更新它们,我将遍历Firebase存储桶中的所有项目,比较两者之间的更新时间,然后如果有新版本,则进行下载.

To update them locally, I am looping through all items within the Firebase Storage bucket, comparing the updated times between the two and then if there is a new version, downloading it.

除了从Firebase提取元数据外,其他所有东西似乎都能正常运行,Firebase文件的最后更新时间始终返回零吗?我觉得这很奇怪,因为它可以很好地下载文件,这意味着不应存在Firebase规则来阻止元数据获取请求或其他任何操作.除非手动添加,上次更新时间默认为0吗?

Everything seems to be working perfectly except the metadata fetching from Firebase, the lastupdated time of the Firebase files is always returning a zero? I find this very odd, because it can download the file just fine, meaning there shouldn't be a Firebase rule blocking a metadata fetch request or anything. Is last updated time by default 0 unless is it manually added?

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");
                }
            });
}

推荐答案

检索元数据是异步操作,该操作发生在后台,而您的主代码仍在继续.通过添加一些简单的日志语句,最容易了解这意味着什么:

Retrieving the metadata is an asynchronous operation, which happens in the background, while your main code continues. It's easiest to see what that means by adding a few simple log statements:

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()");
        }
    }
})

运行时,此代码将打印:

When run, this code prints:

在调用getMetadata()之前

Before calling getMetadata()

调用getMetadata()后

After calling getMetadata()

获得元数据

这可能不是您所期望的,但是它按设计工作,并且恰好解释了代码不起作用的原因:在您的 if(localFile.lastModified()> onlineFileChangeDate [0]时)运行, onlineFileChangeDate [0] = storageMetadata.getUpdatedTimeMillis()尚未将其设置为一个值.

This is probably not what you expected, but it is working as designed, and it explains exactly why your code doesn't work: by the time your if (localFile.lastModified() > onlineFileChangeDate[0]) runs, the onlineFileChangeDate[0] = storageMetadata.getUpdatedTimeMillis() hasn't set it to a value yet.

他的解决方案(以及异步方法调用的任何其他问题)的解决方案是,需要元数据的代码必须位于通过该元数据调用的 onSuccess 内,或从那里调用

The solution for his (and any other problems with asynchronous method calls) is that the code that needs the metadata needs to be inside the onSuccess that gets called with that metadata, or be called from there.

最简单的解决方法:

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");
    }
});

另请参阅:

这篇关于FireBase存储元数据更新时间返回0?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆