Improve FCM service account loading and diagnostics.

Support FCM_SERVICE_ACCOUNT_KEY_FILE, clearer JSON parse errors for common .env mistakes, stop logging credential contents.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Yared Yemane 2026-05-20 08:41:27 -07:00
parent 14d94ec723
commit f7c9eddef5
3 changed files with 16 additions and 7 deletions

View File

@ -4,6 +4,7 @@ import (
"Yimaru-Backend/internal/domain" "Yimaru-Backend/internal/domain"
customlogger "Yimaru-Backend/internal/logger" customlogger "Yimaru-Backend/internal/logger"
"errors" "errors"
"fmt"
"log/slog" "log/slog"
"os" "os"
"strconv" "strconv"
@ -475,7 +476,14 @@ func (c *Config) loadEnv() error {
} }
c.ResendSenderEmail = resendSenderEmail c.ResendSenderEmail = resendSenderEmail
c.FCMServiceAccountKey = os.Getenv("FCM_SERVICE_ACCOUNT_KEY") c.FCMServiceAccountKey = strings.TrimSpace(os.Getenv("FCM_SERVICE_ACCOUNT_KEY"))
if fp := strings.TrimSpace(os.Getenv("FCM_SERVICE_ACCOUNT_KEY_FILE")); fp != "" {
raw, err := os.ReadFile(fp)
if err != nil {
return fmt.Errorf("read FCM_SERVICE_ACCOUNT_KEY_FILE %q: %w", fp, err)
}
c.FCMServiceAccountKey = strings.TrimSpace(string(raw))
}
// Vimeo configuration // Vimeo configuration
vimeoEnabled := os.Getenv("VIMEO_ENABLED") vimeoEnabled := os.Getenv("VIMEO_ENABLED")

View File

@ -69,8 +69,9 @@ func New(
config: cfg, config: cfg,
} }
mongoLogger.Info("FCM_SERVICE_ACCOUNT_KEY value at startup", mongoLogger.Info("FCM credentials config at startup",
zap.String("fcm_service_account_key", cfg.FCMServiceAccountKey), zap.Bool("fcm_credentials_configured", strings.TrimSpace(cfg.FCMServiceAccountKey) != ""),
zap.Int("fcm_service_account_json_len", len(strings.TrimSpace(cfg.FCMServiceAccountKey))),
) )
// Initialize FCM client if service account key is provided // Initialize FCM client if service account key is provided
@ -101,7 +102,7 @@ func (s *Service) initFCMClient() error {
ProjectID string `json:"project_id"` ProjectID string `json:"project_id"`
} }
if err := json.Unmarshal([]byte(s.config.FCMServiceAccountKey), &sa); err != nil { if err := json.Unmarshal([]byte(s.config.FCMServiceAccountKey), &sa); err != nil {
return fmt.Errorf("invalid FCM_SERVICE_ACCOUNT_KEY JSON: %w", err) return fmt.Errorf("invalid FCM service account JSON: %w (hint: private_key must escape newlines as \\n; do not paste multiline JSON into .env unless quoted—use minified one line or FCM_SERVICE_ACCOUNT_KEY_FILE)", err)
} }
if strings.TrimSpace(sa.ProjectID) == "" { if strings.TrimSpace(sa.ProjectID) == "" {
return fmt.Errorf("FCM_SERVICE_ACCOUNT_KEY is missing project_id") return fmt.Errorf("FCM_SERVICE_ACCOUNT_KEY is missing project_id")

View File

@ -727,9 +727,9 @@ func (h *Handler) RegisterDeviceToken(c *fiber.Ctx) error {
func (h *Handler) SendTestPushNotification(c *fiber.Ctx) error { func (h *Handler) SendTestPushNotification(c *fiber.Ctx) error {
title := c.FormValue("title", "Test Push Notification") title := c.FormValue("title", "Test Push Notification")
message := c.FormValue("message", "This is a test push notification from Yimaru Backend") message := c.FormValue("message", "This is a test push notification from Yimaru Backend")
h.mongoLoggerSvc.Info("FCM_SERVICE_ACCOUNT_KEY value during test-push call", h.mongoLoggerSvc.Info("notification test-push diagnostics",
zap.String("fcm_service_account_key", h.Cfg.FCMServiceAccountKey), zap.Bool("fcm_credentials_configured", strings.TrimSpace(h.Cfg.FCMServiceAccountKey) != ""),
zap.String("db_url", h.Cfg.DbUrl), zap.Int("fcm_service_account_json_len", len(strings.TrimSpace(h.Cfg.FCMServiceAccountKey))),
) )
userID, ok := c.Locals("user_id").(int64) userID, ok := c.Locals("user_id").(int64)