Cloud Run & Firebase

Integrare Firebase Admin SDK con Microservizi Cloud Run e Docker per App iOS

Quando le esigenze di calcolo di un'applicazione iOS superano i limiti delle serverless Cloud Functions (es. elaborazione video pesante, algoritmi in Go/Rust, o container Docker custom), **Google Cloud Run** offre la soluzione perfetta. Grazie al **Firebase Admin SDK**, i microservizi su Cloud Run si integrano in modo trasparente con il sistema di autenticazione e con Cloud Firestore.

1. Validazione del Firebase ID Token in un Microservizio Go

L'app iOS invia nell'header Authorization: Bearer <ID_TOKEN> l'ID Token ottenuto da Firebase Auth. Il microservizio backend in Go autentica la richiesta tramite Firebase Admin SDK:

package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"strings"

	firebase "firebase.google.com/go/v4"
	"firebase.google.com/go/v4/auth"
)

var authClient *auth.Client

func initFirebase() {
	ctx := context.Background()
	app, err := firebase.NewApp(ctx, nil)
	if err != nil {
		log.Fatalf("Errore inizializzazione Firebase: %v", err)
	}
	authClient, err = app.Auth(ctx)
	if err != nil {
		log.Fatalf("Errore client Auth Firebase: %v", err)
	}
}

func AuthMiddleware(next http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		authHeader := r.Header.Get("Authorization")
		if authHeader == "" || !strings.HasPrefix(authHeader, "Bearer ") {
			http.Error(w, "Token mancante o non valido", http.StatusUnauthorized)
			return
		}

		idToken := strings.TrimPrefix(authHeader, "Bearer ")
		token, err := authClient.VerifyIDToken(r.Context(), idToken)
		if err != nil {
			http.Error(w, fmt.Sprintf("Token non autorizzato: %v", err), http.StatusUnauthorized)
			return
		}

		// Inserisce l'UID verificato nel contesto della richiesta
		ctx := context.WithValue(r.Context(), "uid", token.UID)
		next.ServeHTTP(w, r.WithContext(ctx))
	}
}

2. Dockerfile Multi-Stage per Cloud Run

Un Dockerfile ottimizzato garantisce che il container su Cloud Run abbia dimensioni minime (sotto i 20 MB) per avvii a freddo istantanei:

FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o server .

FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/server .
EXPOSE 8080
CMD ["./server"]

3. Invocazione lato Client da App SwiftUI

In Swift otteniamo il token aggiornato dall'utente corrente prima di effettuare la chiamata HTTP al servizio Cloud Run:

import FirebaseAuth

func callCloudRunMicroservice() async throws -> Data {
    guard let user = Auth.auth().currentUser else { throw URLError(.userAuthenticationRequired) }
    
    // Recupera l'ID token fresco
    let idToken = try await user.getIDToken()
    
    var request = URLRequest(url: URL(string: "https://my-service-xyz-ew.a.run.app/api/process")!)
    request.httpMethod = "POST"
    request.setValue("Bearer \(idToken)", forHTTPHeaderField: "Authorization")
    
    let (data, response) = try await URLSession.shared.data(for: request)
    return data
}

Conclusione

L'accoppiata Firebase Auth + Cloud Run consente di estendere a dismisura le capacità computazionali delle tue app iOS mantenendo un'autenticazione unificata. Per consulenze su architetture a microservizi Cloud Run, scrivi a diallooyunus@gmail.com.

Yunus Diallo (DialloDev)

Fondatore di Dywtal Digital a Parma (Italia), Cloud & Mobile Architect con competenze in Docker, Go, Laravel e Firebase.