Push Notification — Firebase Cloud Messaging
Muammodan boshlaylik
Foydalanuvchi ilovani yopdi. Lekin unga yangi xabar keldi — bilishi kerak. SMS yuborasizmi? Qimmat. Email? Ko'rmaydi.
Push notification — telefon ekranida chiqadigan bildirishnoma. Telegram, Instagram, delivery ilovalari shunday ishlaydi. Ilovani ochmasdan ham ko'rasiz.
Push Notification qanday ishlaydi?
Sizning server FCM (Firebase) Foydalanuvchi qurilmasi
| | |
| Ilovani ochganda: | |
| |<-- token so'rash ------|
| |--- token berildi ----->|
|<-- token saqlash ----| |
| | |
| Xabar kelganda: | |
|--- push yubor ------>| |
| |--- bildirish --------->|
| | (telefon ekrani)|
FCM (Firebase Cloud Messaging) — vositachi. Sizning serveringiz FCM ga xabar yuboradi, FCM esa foydalanuvchining telefoniga yetkazadi. Telefon o'chiq bo'lmasa ham — saqlab qo'yadi.
FCM token nima?
Har bir qurilma — noyob token. Xuddi pochta adresi kabi. Siz shu adresga xabar jo'natasiz — FCM aniq shu qurilmaga yetkazadi.
Token:
- Ilova o'rnatilganda FCM beradi
- Ilova qayta o'rnatilsa yoki brauzert tozalansa — yangi token
- Sizning serveringiz uni DB da saqlashi kerak
Firebase loyiha yaratish
- console.firebase.google.com
- Yangi loyiha → nom bering
- Project Settings → Service Accounts → Generate new private key
- JSON fayl yuklab olinadi — bu maxfiy kalit
FIREBASE_PROJECT_ID=loyiha-id
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n..."
FIREBASE_CLIENT_EMAIL=firebase-adminsdk@loyiha.iam.gserviceaccount.com
⚠️ JSON faylni Git ga qo'shmang!
.gitignorega qo'shing yoki environment variable dan foydalaning.
O'rnatish
npm install firebase-admin
FCM sozlash
import admin from 'firebase-admin';
admin.initializeApp({
credential: admin.credential.cert({
projectId: process.env.FIREBASE_PROJECT_ID,
privateKey: process.env.FIREBASE_PRIVATE_KEY.replace(/\\n/g, '\n'), // ← muhim!
clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
}),
});
💡
replace(/\\n/g, '\n')—.envfaylda yangi qator\nsifatida yoziladi. Firebase esa haqiqiy yangi qator kutadi.
Push notification yuborish
const pushYuborish = async (token, { sarlavha, matn, malumotlar }) => {
await admin.messaging().send({
token, // ← qaysi qurilmaga
notification: {
title: sarlavha, // ← bildirishnoma sarlavhasi
body: matn, // ← bildirishnoma matni
},
data: malumotlar, // ← ilovaga qo'shimcha ma'lumot (ixtiyoriy)
});
};
// Ishlatish
await pushYuborish(foydalanuvchi.fcmToken, {
sarlavha: 'Yangi xabar',
matn: 'Ali sizga xabar yubordi',
malumotlar: { xabarId: '123', tur: 'chat' },
});
Token ni DB da saqlash
Ilova (frontend) FCM tokenni serverga yuboradi, server DB ga saqlaydi:
// Server — tokenni saqlash
router.post('/fcm-token', authMiddleware, async (req, res) => {
const { token } = req.body;
await db.users.update(
{ fcmToken: token },
{ where: { id: req.user.id } },
);
res.json({ xabar: 'Token saqlandi' });
});
Ko'p qurilmaga yuborish
Bir guruh foydalanuvchilarga — token massivi bilan:
const kopQurilmaPush = async (tokenlar, { sarlavha, matn }) => {
if (tokenlar.length === 0) return;
await admin.messaging().sendEachForMulticast({
tokens: tokenlar, // ← token massivi (max 500)
notification: { title: sarlavha, body: matn },
});
};
// Ishlatish
const tokenlar = users.map((u) => u.fcmToken).filter(Boolean);
await kopQurilmaPush(tokenlar, {
sarlavha: 'Yangilik!',
matn: 'Yangi kurs qo\'shildi',
});
Topic — mavzu bo'yicha yuborish
Barcha foydalanuvchilarga emas — ma'lum guruhga:
// Foydalanuvchini mavzuga qo'shish
await admin.messaging().subscribeToTopic(token, 'yangiliklar');
// Mavzu bo'yicha yuborish
await admin.messaging().send({
topic: 'yangiliklar',
notification: {
title: 'Yangi kurs chiqdi!',
body: 'Express.js kursi yangilandi',
},
});
💡 Topic — yangiliklarni obuna bo'lgan foydalanuvchilarga, sport yangiliklari, promo xabarlar uchun mos. Individual foydalanuvchiga — token.
Tez-tez uchraydigan xatolar
1. FIREBASE_PRIVATE_KEY yangi qator muammosi
// ❌ — \n literal sifatida qoladi
credential: admin.credential.cert({
privateKey: process.env.FIREBASE_PRIVATE_KEY,
})
// ✅ — haqiqiy yangi qatarga aylantirish
privateKey: process.env.FIREBASE_PRIVATE_KEY.replace(/\\n/g, '\n'),
2. Eskirgan token xatosi
messaging/registration-token-not-registered
Sababi: foydalanuvchi ilovani o'chirib o'rnatdi yoki ruxsatni bekor qildi.
Yechim: bu tokenni DB dan o'chiring — yuqoridagi eskirganTokenlar misoli.
3. Token yo'q foydalanuvchiga yuborish
// ❌ — token null bo'lsa crash
await pushYuborish(foydalanuvchi.fcmToken, xabar);
// ✅ — tekshirish
if (foydalanuvchi.fcmToken) {
await pushYuborish(foydalanuvchi.fcmToken, xabar);
}
Xulosa
- FCM — Google ning push notification xizmati; server → FCM → qurilma
- Har qurilma — noyob token; DB da saqlang, token null bo'lsa tekshiring
admin.messaging().send({ token, notification })— bir qurilmagasendEachForMulticast({ tokens })— ko'p qurilmaga (max 500)- Topic — guruh obunasi (yangiliklar, promo)
FIREBASE_PRIVATE_KEYdagi\\nni\nga aylantiring
Keyingi dars: 50-dars: Jest — o'rnatish, birinchi test, describe, it, expect