Conectando API en .Net 5 con firebase storage
Tags: spanish, csharp, firebase, dotnet
Published: 2022-08-04 18:06:00

Actualmente tenemos una variedad de alternativas para guardar documentos o imagenes, sobre todo de opciones en la nube. Una de las alternativas puede ser firebase storage que nos permite conectarnos desde cualquier app indpeendiente el lenguaje. En esta ocasión integraremos una Api en .Net 5 con firebase storage.

Este post esta divididos en tres partes:

1. Creación de proyecto en firebase
2. Crear un usuario en firebase
3. Integración de Api en .Net 5


# Creación de proyecto en firebase

Primero debemos contar con una cuenta de google.
Luego debemos ingresar a la [consola de firebase](https://console.firebase.google.com/)

Creamos un nuevo poyecto
![Nuevo Proyecto](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9fzt3p2hepwl80h80bq2.png)

Paso 1: Nombre del proyecto
![Nombre del proyecto](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/80eip17jwoz9nn6mbmp6.png)

Paso 2: desactivamos google analitycs para el proyecto
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gd46oihsz7lubcjhnh6z.png)

Una vez creado el proyecto seleccionamos storage del menu
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d4phg2mi2syo9tovgc93.png)
 
Iniciamos en modo producción y seleccionamos ubicación

En la sección reglas (rules) copiamos y pegamos el siguiente código
```json
rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}
```

# Crear un usuario en firebase

Para poder acceder a firebase storage debemos crear un usuario en la sección Authentication y le damos a _comenzar_

![sección autenticación](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pjds3m5a8b75we7ezej2.png)
 
Seleccionamos el metodo de autenticación por correo electrónico

![Metodo autenticación](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cfhg2wp9ep9hmrhvsfff.png)
 
![habilitación](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yv07x1uf5brpds1rrrny.png)

En la pestaña users agregamos un nuevo usuario

![nuevo usuario](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n2civqto0enhdxrsrnu0.png)
 
# Integración de Api en .Net 5

Ya realizados los pasos anteriores, estamos listos para conectar nuestra api .Net 5 a firebase. Para ello utilizaremos el código del siguiente repositorio:
[Net Core Firebase Storage](https://github.com/airarrazabald/net-core-firebase)

El proyecto se divide en tres capas

* FirebaseStorageApp
* FirebaseStorageApp.Model
* FirebaseStorageApp.Services

## FirebaseStorageApp

Es nuestra api donde exponemos el endpoint para cargar documentos:

```C#
[HttpPost]
public async Task<IActionResult> Post([FromBody] FileModel file)
{
    string fileUrlFirebase = await Upload(file);
    return Ok(new { fileUrlFirebase });
}

private static async Task<string> Upload(FileModel file)
{
    var fileFromBase64ToStream = FirebaseStorageService.ConvertBase64ToStream(file.FileBase64);
    var fileStream = fileFromBase64ToStream.ReadAsStream();

    string fileUrlFirebase = await FirebaseStorageService.UploadFile(fileStream, file);
    return fileUrlFirebase;
}
```
Para este ejemplo utilizaremos variables de entorno con las keys necesarias para conectarse a firebase. Estas variables debemos reemplazarlas en el archivo _Properties/launchSettings.json_:

```json
"IIS Express": {
    "commandName": "IISExpress",
    "launchBrowser": true,
    "launchUrl": "swagger",
    "environmentVariables": {
    "ASPNETCORE_ENVIRONMENT": "Development",
    "API_KEY_STORAGE": "Your api key storage",
    "AUTH_EMAIL": "your email authentication ",
    "AUTH_PASWORD": "your password autenticaction",
    "BUCKET_STORAGE": "your bucket name"
    }
}
```
AUTH_EMAIL y AUTH_PASWORD: debemos ingresar las configuradas en el paso 2 de este post.

API_KEY_STORAGE: en firebase la obtenemos en Configuración del proyecto < General:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/grkhhhx8sa3c47hrh9lh.png)
 

BUCKET_STORAGE: en firebase la obtenemos en storage omitiendo _gs://_:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7xjlylfxnivwnme8i9ku.png)

## FirebaseStorageApp.Model

En esta capa tenemos la clase con los datos que solicitaremos para guardar documentos. Esta sera utilizada en el controlador y la capa de servicio.

```C#
public class FileModel
{
    [Required(ErrorMessage = "This field is required")]
    [MinLength(5, ErrorMessage = "5 characters is required")]
    public string FileBase64 { get; set; }

    [Required(ErrorMessage = "This field is required")]
    [MinLength(5, ErrorMessage = "5 characters is required")]
    public string FileName { get; set; }

    [Required(ErrorMessage = "This field is required")]
    [MinLength(5, ErrorMessage = "5 characters is required")]
    public string FolderName { get; set; }
}
```

## FirebaseStorageApp.Services

Esta es nuestra capa de servicio en donde conectaremos con firebase.
Para ello debemos instalar dos nugget package, FirebaseAuthentication.net y FirebaseStorage.net:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e9t4n6nz1fm8aij05ug5.png)

Una vez descargados ya podemos concectarnos con la siguiente clase:

```C#
public static class FirebaseStorageService
{
    private static readonly string _apiKey = Environment.GetEnvironmentVariable("API_KEY_STORAGE");
    private static readonly string _bucket = Environment.GetEnvironmentVariable("BUCKET_STORAGE");
    private static readonly string _email = Environment.GetEnvironmentVariable("AUTH_EMAIL");
    private static readonly string _Password = Environment.GetEnvironmentVariable("AUTH_PASWORD");

    public static StreamContent ConvertBase64ToStream(string fileBase64)
    {
        byte[] stringToBase64 = Convert.FromBase64String(fileBase64);
        StreamContent streamContent = new(new MemoryStream(stringToBase64));
        return streamContent;
    }

    public static async Task<string> UploadFile(Stream stream, FileModel file)
    {
        string fileFromFirebaseStorage = string.Empty;
        FirebaseAuthProvider firebaseConfiguration = new(new FirebaseConfig(_apiKey));

        FirebaseAuthLink authConfiguration = await firebaseConfiguration
            .SignInWithEmailAndPasswordAsync(_email, _Password);

        CancellationTokenSource cancellationToken = new();

        FirebaseStorageTask storageManager = new FirebaseStorage(_bucket,
            new FirebaseStorageOptions
            {
                AuthTokenAsyncFactory = () => Task.FromResult(authConfiguration.FirebaseToken),
                ThrowOnCancel = true
            })
            .Child(file.FolderName)
            .Child(file.FileName)
            .PutAsync(stream, cancellationToken.Token);

        try
        {
            fileFromFirebaseStorage = await storageManager;
        }
        catch (Exception e)
        {
        }
        return fileFromFirebaseStorage;
    }
}
```
Explicado el codigo de forma general ya estamos en condiciones de cargar nuestros archivo. En el siguiente link puedes obtener el json dejemplo para probar la api: [Example Body](https://github.com/airarrazabald/net-core-firebase/blob/main/FirebaseStorageApp/ExampleBody/uploadFile.json)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/08yci8q0yn2vxofcdgpe.png)

Al ejecutar el _post_  el endpoint nos devolvera la url para visualizar el documento cargado:

```json
{
  "fileUrlFirebase": "https://firebasestorage.googleapis.com/v0/b/pruebas-fc979.appspot.com/o/documents%2Fpdf_prueba?alt=media&token=6a52c316-661a-48b6-8505-206f3a4b202a"
}
```

Si revisamos en la consola veremos el nuevo archivo cargado
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h5snw41oxftazzonfa2z.png)
 
:briefcase: <a href="http://airarrazabal.netlify.app/" target="_blank">Mi Portafolio</a>