|
|
@@ -1,33 +1,62 @@
|
|
|
import { Capacitor } from "@capacitor/core";
|
|
|
+import { Preferences } from "@capacitor/preferences";
|
|
|
import { PushNotifications } from "@capacitor/push-notifications";
|
|
|
import { registerDeviceToken, removeDeviceToken } from "src/api/deviceToken";
|
|
|
import { userStore } from "src/stores/user";
|
|
|
|
|
|
-// Token FCM do dispositivo, capturado pelo listener "registration" do boot.
|
|
|
-// Fica em escopo de módulo para continuar acessível no logout.
|
|
|
-let deviceToken = null;
|
|
|
+const PUSH_TOKEN_KEY = "fcm_device_token";
|
|
|
|
|
|
export const usePushNotifications = () => {
|
|
|
const isSupported = () => Capacitor.isNativePlatform();
|
|
|
|
|
|
- const setDeviceToken = (token) => {
|
|
|
- deviceToken = token;
|
|
|
+ const setDeviceToken = async (token) => {
|
|
|
+ if (!isSupported()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ await Preferences.set({
|
|
|
+ key: PUSH_TOKEN_KEY,
|
|
|
+ value: JSON.stringify({ token, platform: Capacitor.getPlatform() }),
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ const getDeviceToken = async () => {
|
|
|
+ if (!isSupported()) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ const { value } = await Preferences.get({ key: PUSH_TOKEN_KEY });
|
|
|
+
|
|
|
+ if (!value) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ return JSON.parse(value);
|
|
|
+ } catch {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* Envia o token do dispositivo para a API.
|
|
|
- * Só faz sentido autenticado: sem access token o POST volta 401, o
|
|
|
- * dispositivo fica sem push e o interceptor ainda tenta um refresh à toa.
|
|
|
+ * O token continua guardado depois do envio — o logout precisa dele.
|
|
|
*/
|
|
|
const syncDeviceToken = async () => {
|
|
|
- if (!isSupported() || !deviceToken || !userStore().accessToken) {
|
|
|
+ if (!isSupported() || !userStore().accessToken) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const stored = await getDeviceToken();
|
|
|
+
|
|
|
+ if (!stored?.token) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
- await registerDeviceToken(deviceToken, Capacitor.getPlatform());
|
|
|
+ await registerDeviceToken(stored.token, stored.platform);
|
|
|
} catch {
|
|
|
- // falha silenciosa — não bloqueia o uso do app
|
|
|
+ // falha silenciosa — o token segue guardado para a próxima tentativa
|
|
|
}
|
|
|
};
|
|
|
|
|
|
@@ -36,12 +65,18 @@ export const usePushNotifications = () => {
|
|
|
* depois que o usuário sai da conta.
|
|
|
*/
|
|
|
const unregisterDeviceToken = async () => {
|
|
|
- if (!isSupported() || !deviceToken || !userStore().accessToken) {
|
|
|
+ if (!isSupported() || !userStore().accessToken) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const stored = await getDeviceToken();
|
|
|
+
|
|
|
+ if (!stored?.token) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
- await removeDeviceToken(deviceToken);
|
|
|
+ await removeDeviceToken(stored.token);
|
|
|
} catch {
|
|
|
// falha silenciosa — não pode impedir o logout
|
|
|
}
|
|
|
@@ -73,6 +108,7 @@ export const usePushNotifications = () => {
|
|
|
isSupported,
|
|
|
requestPermissionAndRegister,
|
|
|
setDeviceToken,
|
|
|
+ getDeviceToken,
|
|
|
syncDeviceToken,
|
|
|
unregisterDeviceToken,
|
|
|
};
|