Firebase Cloud Messaging'den (FCM) Pushizo'ya göç
Bildirimleri doğrudan Firebase Cloud Messaging (FCM HTTP v1 API, Firebase Admin SDK ya da Firebase konsolu) ile gönderiyorsanız bu rehber Pushizo'ya geçişi anlatır. Pushizo Android'de FCM'i taşıma katmanı olarak…
Bildirimleri doğrudan Firebase Cloud Messaging (FCM HTTP v1 API, Firebase Admin SDK ya da Firebase konsolu) ile gönderiyorsanız bu rehber Pushizo'ya geçişi anlatır. Pushizo Android'de FCM'i taşıma katmanı olarak kullanmaya devam eder; iOS'ta doğrudan APNs'e, web'de standart Web Push'a (VAPID) gönderir. Dolayısıyla Firebase projeniz ve mevcut Android token'larınız geçerliliğini korur.
1. Neler değişir
| Konu | FCM ile doğrudan gönderim | Pushizo |
|---|---|---|
| Android taşıma | FCM | FCM (aynı Firebase projesi, servis hesabı JSON'u ile) |
| iOS taşıma | FCM → APNs (Firebase iOS SDK gerekir) | Doğrudan APNs (.p8 anahtarı); Firebase iOS SDK gerekmez |
| Web taşıma | FCM web (Firebase VAPID anahtarı) | Standart Web Push, Pushizo'nun ürettiği VAPID çifti |
| Hedefleme | Token, topic, condition | Kullanıcı (external_id), abonelik, segment (tag/özellik/olay filtreleri), alias |
| Kullanıcı modeli | Yok (token listenizi siz tutarsınız) | Kullanıcı + çoklu abonelik; cihaz birleştirme (login) |
| Zamanlama, sessiz saatler, frekans sınırı | Kendi kodunuzda | Platform özelliği (send_after, delivery_time_of_day, app ayarları) |
| Analitik | Firebase Analytics olayları (notification_receive, notification_open) | Teslimat zaman çizelgesi (queued → sent → received → opened), dönüşüm atribüsyonu, webhook olayları |
| E-posta / SMS / in-app / bildirim kutusu | Yok | Dahil |
2. Kanal kurulumu
Android (android_push)
- Firebase konsolu → Project settings → Service accounts → Generate new private key ile servis hesabı JSON'unu indirin (
firebase-adminsdk-…json). Zaten Admin SDK ile gönderim yapıyorsanız aynı dosyadır. - Dashboard → Kanallar → Android Push → JSON'u yükleyin → Doğrula (
POST /v1/apps/{app_id}/channels/android_push/validateFCM'e test bağlantısı yapar). Dosya envelope encryption ile saklanır ve hiçbir yanıtta dönmez. - API ile:
PUT /v1/apps/{app_id}/channels/android_push{ "provider": "fcm", "service_account": { …JSON nesnesi ya da dosya içeriği metni… } }(adminkapsamı; proje değişiyorsaconfirm_project_change: true).
Servis hesabı aynı Firebase projesine ait olduğu sürece uygulamanızdaki mevcut FCM token'ları Pushizo'dan de teslim alır. SENDER_ID_MISMATCH hatası görürseniz servis hesabı başka projeye aittir.
iOS (ios_push)
Firebase iOS SDK'sı APNs token'ını FCM token'ına çevirir; Pushizo bu dolaylamayı kullanmaz. Apple Developer → Keys → APNs anahtarı (.p8), Key ID, Team ID ve Bundle ID'yi Kanallar → iOS Push ekranına girin; ortam olarak Xcode derlemesi için sandbox, TestFlight/App Store için production seçin. Uygulamada Firebase Messaging'i kaldırabilir, FirebaseApp.configure()'ı yalnızca Analytics/Crashlytics için tutabilirsiniz.
Web (web_push)
Kanallar → Web Push etkinleştirildiğinde Pushizo bir VAPID çifti üretir. Firebase'in VAPID anahtarıyla oluşturulmuş tarayıcı abonelikleri taşınamaz; ziyaretçiler Pushizo Web SDK'sı ile yeniden abone olur (izin verilmişse autoResubscribe ile sessizce).
3. Token'ların taşınması
Seçenek A — SDK ile yeniden kayıt (önerilen)
Pushizo SDK'ları ilk açılışta cihazı POST /sdk/v1/apps/{app_id}/subscriptions ile kaydeder; Android'de token FirebaseMessaging.getInstance().token üzerinden alınır, iOS'ta didRegisterForRemoteNotificationsWithDeviceToken ile SDK'ya verilir. Kullanıcı kimliğini bildiğiniz anda Pushizo.login(externalId) çağırın; böylece tüm cihazlar aynı kullanıcıda birleşir. Bu yol ek veri aktarımı gerektirmez; aktif kullanıcılar uygulamayı açtıkça Pushizo'ya geçer.
Seçenek B — CSV içe aktarma (csv_users)
Uygulama açılmadan da hedeflenebilsin istiyorsanız kendi veritabanınızdaki FCM token'larını Pushizo CSV biçiminde dışa aktarıp yükleyin (Firebase'in token'ları dışa aktaran bir API'si yoktur; token'lar sizin sunucunuzdadır).
| Sütun | Değer |
|---|---|
external_id | Kullanıcı kimliğiniz (token yoksa zorunlu) |
channel | android_push (Android FCM token'ı), email, sms. ios_push yalnızca ham APNs token'ı (hex) için; FCM'den gelen iOS token'ları aktarılamaz. web_push CSV ile aktarılamaz. |
token | FCM kayıt token'ı |
status | subscribed (varsayılan), unsubscribed, invalid |
language, timezone | tr, Europe/Istanbul (IANA) |
tags ya da tag.<anahtar> | JSON nesnesi ya da sütun başına tag (ör. tag.topic_news) |
properties ya da property.<anahtar> | Kullanıcı özellikleri |
external_id,channel,token,language,timezone,tag.topic_news,tag.plan
u-1001,android_push,dGhpcyBpcyBhIHRva2Vu…,tr,Europe/Istanbul,1,pro
u-1002,android_push,YW5vdGhlciB0b2tlbg…,en,Europe/London,,free
u-1003,,,tr,,1,curl -X POST "https://api.example.com/v1/apps/app_…/imports" \
-H "Authorization: Bearer hs_live_…" -F type=csv_users -F file=@fcm-tokens.csvİş tamamlanınca stats (processed, created_users, updated_users, created_subscriptions, skipped, errors) ve hatalı satırlar için error_report_url döner. İçe aktarma idempotenttir; (app, channel, token) benzersiz olduğundan aynı token ikinci kez yüklendiğinde güncellenir. Toplu içe aktarma webhook üretmez. Sınır: 50 MB, 500.000 satır (IMPORT_MAX_ROWS); daha büyük dosyaları bölün.
Token FCM tarafından geçersiz bulunursa (UNREGISTERED) ilk gönderimde abonelik otomatik invalid olur; eski token'ları önceden temizlemeniz gerekmez.
4. Topic ve condition → segment / tag
FCM topic'lerinin Pushizo'da karşılığı yoktur; aynı işlevi tag + segment ya da kategori tercihleri sağlar.
| FCM | Pushizo |
|---|---|
FirebaseMessaging.getInstance().subscribeToTopic("news") | Pushizo.User.addTag("topic_news", "1") (SDK) ya da PATCH /v1/apps/{app_id}/users/by/external_id/{id} { "tags": { "topic_news": "1" } } |
unsubscribeFromTopic("news") | Pushizo.User.removeTag("topic_news") ya da { "tags": { "topic_news": null } } |
"topic": "news" ile gönderim | Segment tanımı: { "all": [{ "field": "tags.topic_news", "op": "eq", "value": "1" }] } → target.included_segments: ["seg_…"]; ya da kaydetmeden target.filters ile aynı tanım |
"condition": "'news' in topics && 'tr' in topics" | Segment AST all/any/none grupları: { "all": [{ "field": "tags.topic_news", "op": "eq", "value": "1" }, { "field": "tags.topic_tr", "op": "eq", "value": "1" }] } |
| Kullanıcının kendi seçtiği konu abonelikleri | Kategoriler (Dashboard → Kitle → Kategoriler) + User.setPreferences([{ category: "news", optedIn: true }]); kategoriye kapalı kullanıcı o kategorideki mesajı almaz (suppression_reason: category_opt_out) |
Herkese gönderim ("topic": "all") | target.all: true |
Segment önizleme (POST /v1/apps/{app_id}/segments/preview) sayım ve örnek kullanıcıları döndürür; bir hedef için gönderim yapmadan alıcı sayısı almak için POST /v1/notifications/estimate.
5. Mesaj gövdesi eşlemesi
FCM HTTP v1 message nesnesi ile Pushizo POST /v1/notifications alanları:
| FCM v1 | Pushizo | Not |
|---|---|---|
token / topic / condition | target.include_subscription_ids / target.include_external_ids / target.included_segments / target.filters | Hedef nesnesi zorunludur. |
notification.title / notification.body | headings / contents | Çok dilli nesne: { "tr": "…", "en": "…" }; alıcının diline göre seçilir. |
notification.image | big_picture | Android büyük resim, iOS ek (NSE), web chrome_web_image. |
data | data | Yalnızca metin değerler. Android'de Pushizo her zaman data-only gönderir; görünür bildirimi SDK (PushizoMessagingService) kurar, data alanınız tıklama olayında event.notification.data ile gelir. |
android.priority: HIGH / apns.headers.apns-priority: 10 | priority: 10 | Normal için 5. |
android.ttl / apns-expiration | ttl | Saniye. |
android.collapse_key / apns-collapse-id | collapse_id | |
android.notification.channel_id | android_channel_id | Kanal tanımları: Dashboard → Ayarlar → Android bildirim kategorileri. |
android.notification.icon / color / sound / visibility | small_icon / android_accent_color / android_sound / android_visibility | Renk AARRGGBB; görünürlük 1, 0, -1. |
android.notification.tag (gruplama) | android_group | Grup + özet bildirimi. |
android.notification.click_action / webpush.fcm_options.link | url / app_url | app_url deep link. |
apns.payload.aps.sound | ios_sound | |
apns.payload.aps.badge | ios_badge_type: "SetTo" + ios_badge_count (ya da "Increase") | |
apns.payload.aps.category | ios_category | |
apns.payload.aps.thread-id | thread_id | |
apns.payload.aps.interruption-level | ios_interruption_level | passive, active, time-sensitive, critical |
apns.payload.aps.relevance-score | ios_relevance_score | |
apns.payload.aps.target-content-id | target_content_identifier | |
apns.payload.aps.mutable-content | mutable_content | Görünür bildirimlerde Pushizo zaten 1 gönderir (NSE zengin medya + received). |
apns.payload.aps.content-available (sessiz) | content_available: true | Android'de hs_silent data mesajı, iOS'ta background push. |
apns.fcm_options.image | big_picture ya da ios_attachments | |
webpush.notification.icon / image / badge | chrome_web_icon / chrome_web_image / chrome_web_badge | |
webpush.notification.actions | web_buttons | En fazla 2 düğme. |
webpush.notification.requireInteraction | require_interaction | |
webpush.headers.Topic | web_push_topic | |
fcm_options.analytics_label | name, labels | Panel ve raporlarda görünür. |
android.direct_boot_ok, android.restricted_package_name | — | Desteklenmez. |
Örnek (Firebase Admin SDK → Pushizo Node SDK):
// Önce (firebase-admin)
await admin.messaging().send({
token,
notification: { title: 'Siparişiniz yola çıktı', body: 'Takip bağlantısı içeride', image: 'https://cdn.example.com/box.png' },
data: { order_id: '1001', screen: 'orders' },
android: { priority: 'high', notification: { channelId: 'orders' } },
apns: { payload: { aps: { sound: 'default', 'thread-id': 'orders' } } },
});
// Sonra (@pushizo/node)
await hs.notifications.create({
idempotency_key: 'order-1001-shipped',
target: { include_external_ids: [userId] }, // token yerine kullanıcı
headings: { tr: 'Siparişiniz yola çıktı', en: 'Your order has shipped' },
contents: { tr: 'Takip bağlantısı içeride', en: 'Tracking link inside' },
big_picture: 'https://cdn.example.com/box.png',
data: { order_id: '1001', screen: 'orders' },
priority: 10,
android_channel_id: 'orders',
ios_sound: 'default',
thread_id: 'orders',
});Aynı istek Python/Go/Java/.NET/Ruby SDK'larında notifications.create ile yapılır; sunucu SDK'sı olmayan dillerde curl:
curl -X POST https://api.example.com/v1/notifications \
-H "Authorization: Bearer hs_live_…" -H "Content-Type: application/json" -H "Idempotency-Key: order-1001-shipped" \
-d '{"app_id":"app_…","target":{"include_external_ids":["u-1001"]},"headings":{"tr":"Siparişiniz yola çıktı"},"contents":{"tr":"Takip bağlantısı içeride"},"data":{"order_id":"1001"}}'Data (sessiz) mesajlar
- FCM
data-only mesajı: Pushizo'dacontent_available: true+data. Android SDK bildirim göstermez; iOS'taapns-push-type: backgroundile gönderilir (aps.content-available: 1). iOS arka plan push'larında Apple'ın saat başına birkaç mesaj sınırı geçerlidir. - Uygulamanızda
FirebaseMessagingService.onMessageReceivediçinde yaptığınız özel işleme Pushizo'daPushizo.Notifications.addForegroundLifecycleListener(ön plan) veaddClickListener(tıklama,event.notification.data) ile taşınır. KendiFirebaseMessagingServicesınıfınız kalacaksa manifestte yalnızca biri FCM mesajlarını alır; Pushizo'nunPushizoMessagingService'i manifest merge ile eklenir, kendi servisinizi kaldırın ya da Pushizo dışı mesajları ayırt etmek içindata.hs_delivery_idalanına bakın.
6. Analitik farkları
| Ölçüm | Firebase | Pushizo |
|---|---|---|
| Gönderildi | FCM yanıtı (messageId) | delivery.sent (provider_message_id), mesaj sayacı counts.sent |
| Cihaza ulaştı | Yok (yalnızca GA notification_receive, Android) | received — Android SDK onMessageReceived, iOS NSE, web service worker tarafından raporlanır (confirmed delivery) |
| Açıldı | GA notification_open | opened (+ button_id), webhook delivery.opened |
| Başarısız / geçersiz token | FCM hata kodu, token'ı siz temizlersiniz | delivery.failed (error_code), abonelik otomatik invalid, subscription.invalidated webhook'u |
| Dönüşüm | GA dönüşüm olayı | Olay tanımı is_conversion + atribüsyon penceresi (GET /v1/apps/{app_id}/analytics/conversions) |
| Raporlar | Firebase konsolu | Dashboard → Analitik (teslimat, abonelik büyümesi, olay hacmi, funnel, retention, sağlayıcı sağlığı) ve GET /v1/apps/{app_id}/analytics/* (CSV için format=csv) |
| Ham olay dışa aktarımı | BigQuery export | POST /v1/notifications/{id}/export_events, POST /v1/apps/{app_id}/exports (deliveries, events) |
Firebase Analytics olaylarını (notification_receive, notification_open) kullanan panolarınız varsa, Pushizo webhook'larını (delivery.*) kendi veri ambarınıza yazarak aynı metrikleri üretebilirsiniz; olaylar Pushizo-Event-Id ile tekilleştirilir.
7. Geçiş sırası
- Kanalları kurup doğrulayın; bir test cihazını Test cihazı yapıp Mesajlar → Test push gönder ile teslimatı görün.
- Sunucu tarafında gönderimleri Pushizo'ya taşıyın (önce işlemsel bildirimler, sonra toplu kampanyalar). Topic bazlı gönderimleri segmentlere çevirin.
- Android/iOS uygulamalarına Pushizo SDK'sını ekleyip (
docs/sdk/android.md,docs/sdk/ios.md) yeni sürümü yayınlayın;login(externalId)çağrısını kimlik doğrulama akışına koyun. - Eski sürümlerdeki kullanıcılar için (SDK'sız) Seçenek B ile token'ları içe aktarın; yeni sürüm yayıldıkça bu kayıtlar SDK kayıtlarıyla
(app, channel, token)üzerinden birleşir. - Firebase konsolundan/Admin SDK'dan gönderimi durdurun; servis hesabı anahtarını yalnızca Pushizo'da bırakın.
OneSignal'den Pushizo'ya göç
Pushizo, OneSignal'in kavram modelini (app, abonelik, kullanıcı/alias, tag, segment, şablon, journey) ve SDK yüzeyini (initialize → login → User.addTags → Notifications.requestPermission → Session.sendEvent) bilinçli…
iOS Safari (16.4+) web push ve PWA
iOS 16.4 ve sonrasında Safari, ana ekrana eklenmiş web uygulamalarına (PWA) standart Web Push ile bildirim gönderebilir. Pushizo Web SDK'sı bu akışı ek kod olmadan destekler; farklı olan, kullanıcının siteyi önce ana…