如何在.NET中从Firebase存储获取正确的URL以访问我的文件?

huangapple go评论82阅读模式
英文:

How to get the right URL from firebase storage to access my files in .NET?

问题

我的照片已成功保存在Firebase存储中,尽管我无法通过生成的链接访问它。当我尝试时,收到以下消息:

{
   "error": {
      "code": 400,
      "message": "无效的HTTP方法/URL对。"
   }
}

据我所知,只有在提供的URL不正确的情况下才会发生此错误。对吗?

我将分享保存图片到Firebase的代码片段如下:

if (FirebaseApp.DefaultInstance == null)
{
    FirebaseApp.Create(new AppOptions
    {
        Credential = GoogleCredential.GetApplicationDefault()
    });
}

var bucketName = "bucketname";
var storage = StorageClient.Create();

#region Medidores
if (model.Medidores != null && model.Medidores.Any())
{
    // 省略部分代码...
    foreach (string fileName in Request.Files)
    {
        if (fileName == "Medidores[" + item.Index + "].upFotos")
        {
            HttpPostedFileBase file = Request.Files[fileName];
            if (file != null && file.ContentLength > 0)
            {
                var fileName1 = $"{DateTime.Now:yyyy-MM-dd-HHmm}-{Guid.NewGuid()}-{file.FileName}";

                using (var stream = file.InputStream)
                {
                    var objectName = $"Medidores/{fileName1}";
                    storage.UploadObject(bucketName, objectName, null, stream);

                    var fileUrl = $"https://firebasestorage.googleapis.com/v0/b/{bucketName}/o/{objectName}?alt=media";
                    listaFotos.Add(fileUrl);
                }
            }
        }
    }
    // 省略部分代码...
}
else if (novo)
{
    // 省略部分代码...
}

请注意我保存URL的方式:

var fileUrl = $"https://firebasestorage.googleapis.com/v0/b/{bucketName}/o/{objectName}?alt=media";

我是否漏掉了什么,或者这真的是保存URL的正确方式?我知道在其他语言中,可以通过更改最后一行来声明公共URL:

var fileUrl = storage.GetDownloadUrl(bucketName, objectName);

但在.NET中,由于Firebase库中不包括GetDownloadUrl方法,这是不可能的。我已经根据以下方式更改了“规则”中的权限:

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write;
    }
  }
}

如果有人能指出我在哪里以及我漏掉了什么,我将不胜感激。

英文:

My photos are being successfully saved on my firebase storage although I just cannot access it through the formed link. When I try I receive the following message:

{
  "error": {
    "code": 400,
    "message": "Invalid HTTP method/URL pair."
  }
}

As far as I know this error can only happen if the given URL is not right. Right?

I'll share the whole fragment of my code where I save the picture on the firebase as it follows:

            if (FirebaseApp.DefaultInstance == null)
            {
                //var serviceAccountPath = Path.Combine(rootDirectory, "Credentials", "connect-vistorias-firebase-adminsdk-33gel-857c85cf70.json");
                FirebaseApp.Create(new AppOptions
                {
                    Credential = GoogleCredential.GetApplicationDefault()
                });
            }
                
            var bucketName = "bucketname";
            var storage = StorageClient.Create();

            #region Medidores
            if (model.Medidores != null && model.Medidores.Any())
            {
                foreach (var item in model.Medidores)
                {
                    var prop = item.Id > 0 ? db.VistoriasMedidors.FirstOrDefault(c => c.Id == item.Id) : new VistoriasMedidor();
                    prop.Desligado = item.Desligado;
                    var listaFotos = new List<string>();


                    foreach (string fileName in Request.Files)
                    {
                        if (fileName == "Medidores[" + item.Index + "].upFotos")
                        {
                            HttpPostedFileBase file = Request.Files[fileName];
                            if (file != null && file.ContentLength > 0)
                            {
                                var fileName1 = $"{DateTime.Now:yyyy-MM-dd-HHmm}-{Guid.NewGuid()}-{file.FileName}";

                                using (var stream = file.InputStream)
                                {
                                    var objectName = $"Medidores/{fileName1}";
                                    storage.UploadObject(bucketName, objectName, null, stream);

                                    var fileUrl = $"https://firebasestorage.googleapis.com/v0/b/{bucketName}/o/{objectName}?alt=media";
                                    listaFotos.Add(fileUrl);

                                }
                            }
                        }
                    }

                    prop.Fotos = JsonConvert.SerializeObject(listaFotos);
                    prop.Leitura = item.Leitura;
                    prop.Medidor = item.Medida;

                    if (prop.Id == 0)
                    {
                        prop.IdVistoria = vistoria.Id;
                        prop.IdAppInterno = Guid.NewGuid().ToString();
                        prop.Tipo = item.Tipo;
                        db.VistoriasMedidors.Add(prop);
                        //db.SaveChanges();
                    }
                }
            }
            else if (novo)
            {
                for (int i = 1; i <= 4; i++)
                {
                    var prop = new VistoriasMedidor();
                    prop.Desligado = true;
                    var listaFotos = new List<string>();

                    prop.Fotos = Newtonsoft.Json.JsonConvert.SerializeObject(listaFotos);
                    prop.Leitura = "";
                    prop.Medidor = "";

                    if (prop.Id == 0)
                    {
                        prop.IdVistoria = vistoria.Id;
                        prop.IdAppInterno = Guid.NewGuid().ToString();
                        prop.Tipo = i;
                        db.VistoriasMedidors.Add(prop);
                        //db.SaveChanges();
                    }
                }

            }

Please pay attention on how I am saving my URL:

var fileUrl = $"https://firebasestorage.googleapis.com/v0/b/{bucketName}/o/{objectName}? alt=media";

Am I missing something or it is really the right way to save the URL? I know in other languages you can declare a public URL by changing the last line for:

var fileUrl = storage.GetDownloadUrl(bucketName, objectName);

But in .NET it is just not possible since GetDownloadUrl is not included in the firebase library. I already changed permission in the "Rules" as it follows:

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write;
    }
  }
}

I would be extremely thankful if anyone could point where and what I am missing.

答案1

得分: 0

安全规则仅在通过Firebase SDK访问数据时应用。看起来您想生成一个直接访问数据的URL,在这种情况下,安全规则将不会被应用。

如果您使用Firebase提供的客户端SDK,您确实可以指示它生成所谓的下载URL,该URL提供对文件的公开只读访问权限。这种方法(正如您所发现的)在非Firebase SDK(例如Google Cloud SDK for C#/.NET)中是不存在的。

在这些平台上,您的选择有两种:

  • 使存储桶中的所有文件都可以公开访问,如使数据公开文档中所示。在那一点上,访问各个文件的URL将类似于您上面创建的URL。

  • 为每个文件生成一个签名URL,类似于下载URL,但提供了在定义的时间段内(可以是任意长)公开访问权限。有关更多信息,请参阅使用Cloud Storage库(V4)创建对象的GET签名URL的文档,其中还包含C#中的代码示例。

英文:

The security rules are only applied when you access the data through a Firebase SDK. It seems like you want to generate a direct URL to access it, in which case the security rules are never applied.

If you have a Firebase-provided client-side SDK, you can indeed instruct it to generate a so-called download URL, which provides public read-only access to the file. This method does (as you found) not exist in non-Firebase SDKs, such as the Google Cloud SDK for C#/.NET.

In such platforms, your options are to:

  • Make all files in the bucket publicly accessible, as shown in the documentation on making data public. At that point the URL to access the individual files will look similar to what you've created above.

  • Generate a signed URL for each file, which is similar to a download URL, but provides public access for a defined time period (which can be as long as you want). For more on this, see the documentation on Creating a GET-signed URL for an object using Cloud Storage libraries (V4), which also contains a code sample in C#.

huangapple
  • 本文由 发表于 2023年6月12日 02:11:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/76451882.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定