Files
mobile-android/docs/FCM_SETUP.md
k1ngsterr1 569aa34432 feat: Add comprehensive encryption architecture documentation for Rosette Messenger
feat: Implement Firebase Cloud Messaging (FCM) integration documentation for push notifications

docs: Outline remaining tasks for complete FCM integration in the project

fix: Resolve WebSocket connection issues after user registration
2026-01-17 19:04:05 +05:00

307 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Firebase Cloud Messaging (FCM) Integration
## Обзор
Android приложение использует **Firebase Cloud Messaging (FCM)** для push-уведомлений о новых сообщениях.
## Архитектура
### Клиент (Android)
1. **При старте приложения** (`MainActivity.kt`):
- Инициализируется Firebase
- Получается FCM токен
- Токен отправляется на сервер через протокол
2. **При получении нового токена** (`RosettaFirebaseMessagingService.kt`):
- Вызывается `onNewToken()`
- Новый токен отправляется на сервер
3. **При получении push-уведомления** (`RosettaFirebaseMessagingService.kt`):
- Вызывается `onMessageReceived()`
- Показывается системное уведомление
- При клике открывается соответствующий чат
### Протокол
**Packet ID: 0x0A - PacketPushToken**
Формат пакета:
```
[PacketID: 0x0A (2 bytes)]
[privateKey: String]
[publicKey: String]
[pushToken: String]
[platform: String] // "android" или "ios"
```
### Сервер
Сервер должен:
1. Получить `PacketPushToken` от клиента
2. Сохранить в БД связку: `publicKey -> fcmToken`
3. При получении нового сообщения для пользователя:
- Найти FCM токен по `publicKey` получателя
- Отправить push через FCM HTTP API
## Настройка Firebase
### 1. Создать Firebase проект
1. Перейти на [Firebase Console](https://console.firebase.google.com/)
2. Создать новый проект или выбрать существующий
3. Добавить Android приложение
### 2. Настройка Android app
**Package name:** `com.rosetta.messenger`
1. В Firebase Console → Project Settings → General
2. Скачать `google-services.json`
3. Поместить файл в `rosetta-android/app/google-services.json`
### 3. Структура google-services.json
```json
{
"project_info": {
"project_number": "YOUR_PROJECT_NUMBER",
"project_id": "your-project-id",
"storage_bucket": "your-project-id.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:YOUR_PROJECT_NUMBER:android:xxxxx",
"android_client_info": {
"package_name": "com.rosetta.messenger"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "YOUR_API_KEY"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}
```
### 4. Получить Server Key
1. Firebase Console → Project Settings → Cloud Messaging
2. Скопировать **Server Key** (Legacy)
3. Использовать на сервере для отправки уведомлений
## Отправка Push-уведомлений с сервера
### FCM HTTP v1 API (рекомендуется)
```bash
POST https://fcm.googleapis.com/v1/projects/YOUR_PROJECT_ID/messages:send
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
{
"message": {
"token": "FCM_DEVICE_TOKEN_FROM_CLIENT",
"notification": {
"title": "Имя отправителя",
"body": "Текст сообщения"
},
"data": {
"type": "new_message",
"sender_public_key": "SENDER_PUBLIC_KEY",
"sender_name": "Имя отправителя",
"message_preview": "Текст сообщения"
},
"android": {
"priority": "HIGH",
"notification": {
"channel_id": "messages",
"sound": "default",
"notification_priority": "PRIORITY_HIGH"
}
}
}
}
```
### Legacy FCM API (проще для начала)
```bash
POST https://fcm.googleapis.com/fcm/send
Authorization: key=YOUR_SERVER_KEY
Content-Type: application/json
{
"to": "FCM_DEVICE_TOKEN_FROM_CLIENT",
"notification": {
"title": "Имя отправителя",
"body": "Текст сообщения",
"sound": "default"
},
"data": {
"type": "new_message",
"sender_public_key": "SENDER_PUBLIC_KEY",
"sender_name": "Имя отправителя",
"message_preview": "Текст сообщения"
},
"priority": "high",
"android": {
"priority": "HIGH",
"notification": {
"channel_id": "messages"
}
}
}
```
## Пример серверной логики (Node.js)
```javascript
const admin = require("firebase-admin");
// Инициализация Firebase Admin SDK
const serviceAccount = require("./path/to/serviceAccountKey.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
});
// База данных с токенами (пример)
const userTokens = new Map(); // publicKey -> fcmToken
// Обработка PacketPushToken (0x0A)
function handlePushToken(packet) {
const { publicKey, pushToken, platform } = packet;
console.log(`📱 Saving FCM token for user ${publicKey.slice(0, 10)}...`);
userTokens.set(publicKey, pushToken);
}
// Отправка push-уведомления
async function sendPushNotification(
recipientPublicKey,
senderPublicKey,
senderName,
messageText
) {
const fcmToken = userTokens.get(recipientPublicKey);
if (!fcmToken) {
console.log("⚠️ No FCM token for user");
return;
}
const message = {
token: fcmToken,
notification: {
title: senderName,
body: messageText,
},
data: {
type: "new_message",
sender_public_key: senderPublicKey,
sender_name: senderName,
message_preview: messageText,
},
android: {
priority: "HIGH",
notification: {
channelId: "messages",
sound: "default",
priority: "PRIORITY_HIGH",
},
},
};
try {
const response = await admin.messaging().send(message);
console.log("✅ Push notification sent:", response);
} catch (error) {
console.error("❌ Error sending push:", error);
// Если токен невалиден - удаляем из БД
if (
error.code === "messaging/invalid-registration-token" ||
error.code === "messaging/registration-token-not-registered"
) {
userTokens.delete(recipientPublicKey);
}
}
}
// Когда приходит PacketMessage
function handleNewMessage(packet) {
const { fromPublicKey, toPublicKey, content } = packet;
// Отправляем push получателю (если он не онлайн)
sendPushNotification(toPublicKey, fromPublicKey, "User", "New message");
}
```
## Тестирование
### 1. Проверка токена
```kotlin
// В логах Android Studio должно быть:
🔔 FCM token: XXXXXXXXXXXX...
```
### 2. Тест через Firebase Console
1. Firebase Console → Cloud Messaging
2. Send test message
3. Вставить FCM токен из логов
4. Отправить
### 3. Проверка формата пакета
```
Packet 0x0A должен содержать:
- PacketID: 0x0A (10 в decimal)
- privateKey: хеш приватного ключа
- publicKey: публичный ключ пользователя
- pushToken: FCM токен устройства
- platform: "android"
```
## Troubleshooting
### Токен не получается
1. Проверить `google-services.json` в `app/google-services.json`
2. Проверить package name совпадает: `com.rosetta.messenger`
3. Rebuild проект
4. Проверить Google Play Services на устройстве
### Уведомления не приходят
1. Проверить разрешение на уведомления (Android Settings)
2. Проверить Server Key на сервере
3. Проверить FCM токен актуален
4. Проверить формат JSON в FCM API запросе
### Уведомления приходят, но не открывают чат
Проверить data payload содержит `sender_public_key`
## Полезные ссылки
- [Firebase Console](https://console.firebase.google.com/)
- [FCM Documentation](https://firebase.google.com/docs/cloud-messaging)
- [Android Setup Guide](https://firebase.google.com/docs/cloud-messaging/android/client)
- [FCM HTTP Protocol](https://firebase.google.com/docs/cloud-messaging/http-server-ref)