firebase implementation
Gitea Actions / Deploy (push) Successful in 1m14s

This commit is contained in:
vadim committed 2026-10-16 16:56:34 +03:00
1 parent a0c557f9b2
commit 2d4b8ea9cf
17 files changed
+1542 -12

No files matched your search

+3 -1
View File
@@ -39,6 +39,8 @@ export const apiClient = {
get: <T>(path: string) => request<T>(path),
post: <T>(path: string, body?: unknown) => request<T>(path, { method: 'POST', body: JSON.stringify(body) }),
patch: <T>(path: string, body?: unknown) => request<T>(path, { method: 'PATCH', body: JSON.stringify(body) }),
put: <T>(path: string, body?: unknown) => request<T>(path, { method: 'PUT', body: JSON.stringify(body) }),
upload: <T>(path: string, form: FormData) => request<T>(path, { method: 'POST', body: form }),
delete: (path: string) => request<void>(path, { method: 'DELETE' }),
delete: (path: string, body?: unknown) =>
request<void>(path, { method: 'DELETE', body: body === undefined ? undefined : JSON.stringify(body) }),
}
+81
View File
@@ -0,0 +1,81 @@
import { initializeApp } from 'firebase/app'
import {
getMessaging,
register,
unregister,
onRegistered,
onUnregistered,
onMessage,
isSupported,
type MessagePayload,
type Unsubscribe,
} from 'firebase/messaging'
export type PushOptions = {
// Вызывается при каждой (пере)регистрации: первый register(), смена FID,
// событие pushsubscriptionchange. Здесь отправляйте FID на бэкенд.
onInstallationId: (installationId: string) => void
// FID больше не активен (unregister) — его нужно удалить на бэкенде
onInstallationIdRemoved?: (installationId: string) => void
// Сообщения, пришедшие, пока вкладка открыта
onForeground?: (payload: MessagePayload) => void
}
const VAPID_KEY = 'BPr-D-K2uyc9GDNaIBg1JpnjWlNPw-btaKXowDWgvIUZ14l8IBk421x9iJDlGBB_rFSfsK6HCOOfvW0-l88yGPg'
const firebaseConfig = {
apiKey: 'AIzaSyAKY4nPht7-YsIQfhcECxVwZFx7iAnCQSM',
authDomain: 'ulitka-c811b.firebaseapp.com',
projectId: 'ulitka-c811b',
storageBucket: 'ulitka-c811b.firebasestorage.app',
messagingSenderId: '82243223520',
appId: '1:82243223520:web:2c0e68358f8d5f2d2a7585',
measurementId: 'G-CMDB21T1WG',
}
const app = initializeApp(firebaseConfig)
let started = false
let unsubscribers: Unsubscribe[] = []
export async function enablePush(options: PushOptions): Promise<NotificationPermission | 'unsupported'> {
if (!(await isSupported())) return 'unsupported'
const result = await Notification.requestPermission()
if (result === 'granted') await startMessaging(options)
return result
}
export async function autoRequestPush(options: PushOptions): Promise<void> {
if (!(await isSupported())) return
if (Notification.permission === 'granted') return startMessaging(options)
}
// Отписывает браузер от FCM. Колбэк onInstallationIdRemoved сработает через onUnregistered.
export async function disablePush(): Promise<void> {
if (!started) return
await unregister(getMessaging(app))
unsubscribers.forEach((unsubscribe) => unsubscribe())
unsubscribers = []
started = false
}
async function startMessaging({ onInstallationId, onInstallationIdRemoved, onForeground }: PushOptions): Promise<void> {
if (started) return
started = true
try {
const messaging = getMessaging(app)
unsubscribers = [
onRegistered(messaging, onInstallationId),
onUnregistered(messaging, (fid) => onInstallationIdRemoved?.(fid)),
onMessage(messaging, (payload) => onForeground?.(payload)),
]
await register(messaging, { vapidKey: VAPID_KEY })
} catch (err) {
unsubscribers.forEach((unsubscribe) => unsubscribe())
unsubscribers = []
started = false
throw err
}
}