142 lines
3.2 KiB
Go
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,
|
|
})
|
|
}
|