当前位置: 首页 > 知识库问答 >
问题:

FireBase存储元数据-更新时间返回0?

郎泰平
2023-03-14

我正在尝试使用Firebase存储和同步几个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个答案

轩辕华辉
2023-03-14

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

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()尚未将其设置为值。

his(以及异步方法调用的任何其他问题)的解决方案是,需要元数据的代码需要在用该元数据调用的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");
    }
});

另请参阅:

  • GetContactsFromFireBase()方法返回空列表
 类似资料:
  • 这就是我的设想。我有一个POJO类,我们称之为Car,声明如下: 在那个类中,列表 图片应该包含到我实际上传图片的Firebase存储的链接。由于Firebase函数的异步根,我在这方面遇到了问题。在第一个时刻,pictures列表具有图像的本地路径,因为我不希望用户在完成向Firebase数据库添加记录所需的所有步骤之前上传任何内容。所以,我只保存图像的本地路径。但是,一旦数据保存到云中,我当然

  • 我花了几个小时来查找为什么我的代码没有从这个结构X:/中检索到文件“firstname”的原因 当我在debug中时,我可以看到Firebase检索与“firstname”相同级别的所有其他字段,但最后一个字段始终为null,即使它中有有效数据。 这是我创建FireStoreRecyclerOptions的行: 这是我的QueryFireStore: 而X类是一个POJO,包含以下数据结构:

  • 问题内容: 我只是在想,是否可以使用Swift将时间存储在Firebase中?我之所以问是因为我要创建一个应用程序,当我创建一个特定的对象时,该对象将启动一个计时器,该计时器从创建之日起24小时开始递减计数。这24小时到期后,该对象将被删除。我还想显示一个倒数计时器,以显示该对象在删除之前还剩下多长时间。 我尝试将小时和分钟作为整数存储到数据库中,但这似乎效率不高,因为我不得不担心AM / PM,

  • 数据更新时间指当前可分析数据是什么时间准备好的。通过它你可以了解到,目前数据的时效性。 eg:当数据更新时间显示为3分钟前,则代表可以查看约3分钟之前的数据;当数据更新时间显示00:00~6:00的某一个时间,则代表可以查看前一天以及更早的数据。 1.数据更新频率 (1) 当应用刚创建时,支持分钟级别数据更新频率,即刚上传的数据在几分钟内就能在系统中看到 (2) 当应用累计事件触发超过10000

  • 假设我们有一个带有自定义方法的Spring数据存储库接口... 此方法只是设置实体的 deletedAt 字段,ok。有没有办法允许此方法返回 的更新版本? 明显地 …不起作用,因为… java.lang.IllegalArgumentException:修改查询只能使用void或int/Integer作为返回类型! 安宁是否知道另一种轻松允许这种情况的方法,当然除了明显的“在存储库和调用者之间添

  • 我在我的项目中集成了Firebase实时数据库。当活动打开时,我检查用户是否已经在数据库中检查,为此,我从调用方法。检查下面的代码。 问题:当数据插入firebase并在中回调/触发器时,如何更新/接收数据?