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.
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#.