Files
backend_jupiter/controllers/notificationController.go
2026-05-25 11:45:56 +05:30

142 lines
3.2 KiB
Go

package controllers
import (
"context"
"nearle/domain"
"nearle/models"
"nearle/utils"
"net/http"
"sync"
firebase "firebase.google.com/go"
"firebase.google.com/go/messaging"
"github.com/gofiber/fiber/v2"
"google.golang.org/api/option"
)
var (
fcmApp *firebase.App
fcmClient *messaging.Client
fcmOnce sync.Once
fcmInitErr error
)
// getFCMClient handles the singleton initialization of Firebase
func getFCMClient() (*messaging.Client, error) {
fcmOnce.Do(func() {
ctx := context.Background()
opt := option.WithCredentialsFile("nearle-gear-firebase-adminsdk-l9oha-23ca3b3609.json")
app, err := firebase.NewApp(ctx, nil, opt)
if err != nil {
fcmInitErr = err
return
}
fcmApp = app
client, err := app.Messaging(ctx)
if err != nil {
fcmInitErr = err
return
}
fcmClient = client
})
return fcmClient, fcmInitErr
}
func NotifyUser(c *fiber.Ctx) error {
// Parse the request body
var body struct {
Token string `json:"token"`
Notification models.FcmNotification `json:"notification"`
Data map[string]string `json:"data"`
}
if err := c.BodyParser(&body); err != nil {
utils.Error("NotifyUser parsing body error", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"code": http.StatusBadRequest,
"message": err.Error(),
"status": false,
})
}
// Use shared client instead of initializing on every request
client, err := getFCMClient()
if err != nil {
utils.Error("NotifyUser Firebase initialization error", "error", err)
return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{
"code": http.StatusInternalServerError,
"message": "FCM Initialization error: " + err.Error(),
"status": false,
})
}
// Construct the message
message := &messaging.Message{
Token: body.Token,
Notification: &messaging.Notification{
Title: body.Notification.Title,
Body: body.Notification.Body,
},
Android: &messaging.AndroidConfig{
Priority: "high",
Notification: &messaging.AndroidNotification{
Sound: "ring",
},
},
Data: body.Data,
}
// Send the message
_, err = client.Send(context.Background(), message)
if err != nil {
utils.Error("NotifyUser FCM send error", "error", err)
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
"code": http.StatusInternalServerError,
"message": err.Error(),
"status": false,
})
}
// Return structured response
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "FCM message sent successfully!",
"status": true,
})
}
func NotifyUsers(c *fiber.Ctx) error {
var data models.Notifications
if err := c.BodyParser(&data); err != nil {
utils.Error("NotifyUsers parsing body error", "error", err)
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
"code": http.StatusBadRequest,
"message": err.Error(),
"status": false,
})
}
result := domain.SendNotifications(data)
if !result {
utils.Error("NotifyUsers bulk send failed")
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Failed to send notifications",
"status": false,
})
}
return c.JSON(fiber.Map{
"code": http.StatusOK,
"message": "Success",
"status": true,
})
}