简体   繁体   English

如何在 Unity 中获取 Firebase 应用程序目录中的文件列表

[英]How to get a list of files in a directory of a Firebase App in Unity

I am trying to get a list of all files in a directory of the Firebase app.我正在尝试获取 Firebase 应用目录中所有文件的列表。 It seems that this is possible on all platforms but Unity.似乎这在所有平台上都是可能的,但 Unity 除外。 All platforms excluding Unity have an option of "List Files" here .除 Unity 外的所有平台都可以在此处选择“列出文件”。 Is there some other way to get a list of all the files?有没有其他方法可以获取所有文件的列表?

I also tried to maintain a text file with such entry but it takes a long time to first download the text file, upload the video and again upload the updated text file.我也尝试用这样的条目维护一个文本文件,但是首先下载文本文件、上传视频并再次上传更新的文本文件需要很长时间。 (There some other issues as well due to download being async). (由于下载是异步的,还有一些其他问题)。

Basically my code currently looks like this:基本上我的代码目前看起来像这样:

public void UploadVideoandUpdateText()
{
    //Downloading Text file
    details_text_ref.GetFileAsync(local_text_url).ContinueWith(task => {
            if (!task.IsFaulted && !task.IsCanceled)
            {
                Debug.Log("File downloaded.");
            }
        });

    //Updating local_text_url and downloading it again
    details_text_ref.PutFileAsync(local_text_url).ContinueWith((Task<StorageMetadata> task) => {
            if (task.IsFaulted || task.IsCanceled)
            {
                Debug.Log(task.Exception.ToString());
                // Uh-oh, an error occurred!
            }
            else
            {
                // Metadata contains file metadata such as size, content-type, and download URL.
                Firebase.Storage.StorageMetadata metadata = task.Result;
                string download_url = details_text_ref.GetDownloadUrlAsync().ToString();
                Debug.Log("Finished uploading...");
                Debug.Log("download url = " + download_url);
            }
        });

    //Finally uploading the video
    video_ref.PutFileAsync(full_path_video).ContinueWith((Task<StorageMetadata> task) => {
            if (task.IsFaulted || task.IsCanceled)
            {
                Debug.Log(task.Exception.ToString());
                // Uh-oh, an error occurred!
            }
            else
            {
                // Metadata contains file metadata such as size, content-type, and download URL.
                Firebase.Storage.StorageMetadata metadata = task.Result;
                string download_url = video_ref.GetDownloadUrlAsync().ToString();
                Debug.Log("Finished uploading...");
                Debug.Log("download url = " + download_url);
            }
        });
}

The above is not working due to the downloads being in async.由于下载是异步的,上述内容不起作用。 Is there a solution to make the function wait till the Details txt file is downloaded.是否有解决方案让函数等待下载详细信息 txt 文件。 Or even better, to have a direct method to view all uploaded files in a directory.或者甚至更好,有一个直接的方法来查看目录中所有上传的文件。

Anyone else coming across this issue, I've managed to find a solution.其他人遇到这个问题,我已经设法找到了解决方案。

Note: This doesn't answer the original question specifically, but general to what the question is asking without any description注意:这并没有具体回答原始问题,而是对问题提出的一般问题没有任何描述

How to get all objects within a Firebase folder如何获取 Firebase 文件夹中的所有对象

Seems easy enough right?看起来很容易吧? Just request to get an object array of the data.只需请求获取数据的对象数组。 Wrong... If the data is kept in a format like this:错误...如果数据以这样的格式保存:

Folder
-- 0
---- Name: "Bob"
---- Age: 26
-- 1
---- Name: "Me"
---- Age: 29
-- 2
---- Name: "Jeff"
---- Age: 24

Then it can be retrieved into an object array.然后它可以被检索到一个对象数组中。

But notice that the sub folders within the folders need to be indexes in order for Firebase to recognize it as an array.但请注意,文件夹中的子文件夹需要是索引,以便 Firebase 将其识别为数组。 This isn't normally how people might keep data.这通常不是人们保存数据的方式。 A normal Firebase structure might look like this:正常的 Firebase 结构可能如下所示:

Folder
-- Bob
---- Name: "Bob"
---- Age: 26
-- Me
---- Name: "Me"
---- Age: 29
-- Jeff
---- Name: "Jeff"
---- Age: 24

Notice that now, the sub folders aren't indexed, and so the JSON isn't an array anymore, but another folder.请注意,现在子文件夹未编入索引,因此 JSON 不再是数组,而是另一个文件夹。 This cannot be read as an array of objects.这不能作为对象数组读取。 So what do we do?那么我们该怎么办?

We can simply get a dictionary containing keys of type string, and values of type object .我们可以简单地获取一个包含 string 类型键和 object 类型值的字典 This way, we can keep the names of the sub folders, and not have to change them into array index numbers.这样,我们可以保留子文件夹的名称,而不必将它们更改为数组索引号。

However to do this, we need to get the raw JSON first.但是要做到这一点,我们需要先获取原始 JSON。 Here's a way of doing it in C# using a WebClient:这是使用 WebClient 在 C# 中执行此操作的一种方法:

static string GetJson(string url)
{
    using (var w = new WebClient())
    {
        var json_data = string.Empty;

        // attempt to download JSON data as a string
        try
        {
            json_data = w.DownloadString(url);
            Debug.Log(json_data);
        }
        catch (Exception) { }

        return json_data;
    }
}

The 'url' parameter is the link to our firebase database, alongside our folder name. 'url' 参数是我们的 firebase 数据库的链接,旁边是我们的文件夹名称。 For example: "https://myprojectid.firebaseio.com/Folder.json".例如:“https://myprojectid.firebaseio.com/Folder.json”。 Remember to add .json at the end to get the raw json data.记得在最后添加 .json 以获取原始 json 数据。

Next, we need a JSON deserializer to convert our json data into our dictionary.接下来,我们需要一个 JSON 反序列化器来将我们的 json 数据转换成我们的字典。 I'm using the Newtonsoft.Json NuGet package, which you can install and place the .dll file into your Assets/Plugins folder.我正在使用 Newtonsoft.Json NuGet 包,您可以安装该包并将 .dll 文件放入 Assets/Plugins 文件夹中。 Create it if you haven't already.如果您还没有创建它。

Then, to convert it into an object, we just write:然后,要将其转换为对象,我们只需编写:

static Dictionary<string, Person> GetObjects(string json)
{
    var values = JsonConvert.DeserializeObject<Dictionary<string, Person>>(json);
    return values;
}

This should return a dictionary containing all objects within your folder, hopefully.这应该返回一个包含文件夹中所有对象的字典,希望如此。 The object class is called person.对象类称为人。 Quite simple:非常简单:

public class Person
{
    public string Name;
    public int Age;

    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }  
}

Hopefully this helps someone down the line.希望这可以帮助某人下线。 Tag me if you have any issues.如果您有任何问题,请标记我。

Update更新

There is a much simpler and faster way to do this.有一种更简单、更快捷的方法可以做到这一点。 I've managed to find an article explaining the usage of a REST API to put and get objects from a Firebase database.我设法找到了一篇文章,解释了使用 REST API 从 Firebase 数据库放置和获取对象的用法。

It also explains how to get a collection of objects from a folder using a custom serializer.它还解释了如何使用自定义序列化程序从文件夹中获取对象集合。 It's a lot quicker than the WebClient solution above.它比上面的 WebClient 解决方案快得多。 Here's the link:这是链接:

Firebase in Unity with REST API Unity 中的 Firebase 和 REST API

If you use unity after 2017.3 and use .Net 4.x Scripting Backend, use async/await.如果您在 2017.3 之后使用 unity 并使用 .Net 4.x Scripting Backend,请使用 async/await。

Then your code will be like this然后你的代码会是这样的

public async void UploadVideoandUpdateText()
{
    await details_text_ref.GetFileAsync(local_text_url);
    var metadata = await details_text_ref.PutFileAsync(local_text_url);
    string download_url = (awit details_text_ref.GetDownloadUrlAsync()).ToString();
    await video_ref.PutFileAsync(full_path_video);
}

See this article for async / await.有关 async/await 的信息,请参阅这篇文章。 https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/ https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/

but in case you can't use async/await, seperate each async operation to function and connect with ContinueWith().但如果您不能使用 async/await,请将每个异步操作分开运行并使用 ContinueWith() 连接。

public void UploadVideoandUpdateText()
{
    GetFile.ContinueWith(PutText).ContinueWith(PutVideo);
}

private Task GetFile()
{
    return details_text_ref.GetFileAsync(local_text_url);
}
private Task<StorageMetadata> GetText()
{
    return details_text_ref.PutFileAsync(local_text_url);
}
private Task<StorageMetadata> PutText()
{
    return details_text_ref.PutFileAsync(local_text_url);
}
private Task<StorageMetadata> PutVideo()
{
    return details_text_ref.PutFileAsync(full_path_video);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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