Files
hMarket/backend/src/config/firebase.js

371 lines
9.2 KiB
JavaScript
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.
const admin = require('firebase-admin');
let firebaseApp = null;
/**
* Firebase Admin SDK'yı başlat
*/
const initializeFirebase = () => {
try {
// Eğer zaten başlatılmışsa, mevcut instance'ı döndür
if (firebaseApp) {
return firebaseApp;
}
// Environment variables'dan Firebase config'i al
const firebaseConfig = {
type: process.env.FIREBASE_TYPE,
project_id: process.env.FIREBASE_PROJECT_ID,
private_key_id: process.env.FIREBASE_PRIVATE_KEY_ID,
private_key: process.env.FIREBASE_PRIVATE_KEY?.replace(/\\n/g, '\n'),
client_email: process.env.FIREBASE_CLIENT_EMAIL,
client_id: process.env.FIREBASE_CLIENT_ID,
auth_uri: process.env.FIREBASE_AUTH_URI,
token_uri: process.env.FIREBASE_TOKEN_URI,
auth_provider_x509_cert_url: process.env.FIREBASE_AUTH_PROVIDER_X509_CERT_URL,
client_x509_cert_url: process.env.FIREBASE_CLIENT_X509_CERT_URL
};
// Gerekli environment variables'ların varlığını kontrol et
const requiredFields = ['project_id', 'private_key', 'client_email'];
const missingFields = requiredFields.filter(field => !firebaseConfig[field]);
if (missingFields.length > 0) {
console.warn(`⚠️ Firebase konfigürasyonu eksik: ${missingFields.join(', ')}`);
console.warn('Push notification özelliği devre dışı bırakıldı.');
return null;
}
// Firebase Admin SDK'yı başlat
firebaseApp = admin.initializeApp({
credential: admin.credential.cert(firebaseConfig),
projectId: firebaseConfig.project_id
});
console.log('✅ Firebase Admin SDK başarıyla başlatıldı');
return firebaseApp;
} catch (error) {
console.error('❌ Firebase başlatma hatası:', error.message);
console.warn('Push notification özelliği devre dışı bırakıldı.');
return null;
}
};
/**
* Firebase Messaging instance'ını al
*/
const getMessaging = () => {
if (!firebaseApp) {
console.warn('Firebase başlatılmamış. Push notification gönderilemez.');
return null;
}
try {
return admin.messaging();
} catch (error) {
console.error('Firebase Messaging alınamadı:', error);
return null;
}
};
/**
* Tek bir cihaza push notification gönder
* @param {string} token - Device token
* @param {object} notification - Notification objesi
* @param {object} data - Ek veri
* @returns {Promise<object>} Gönderim sonucu
*/
const sendToDevice = async (token, notification, data = {}) => {
const messaging = getMessaging();
if (!messaging) {
return { success: false, error: 'Firebase Messaging kullanılamıyor' };
}
try {
const message = {
token: token,
notification: {
title: notification.title,
body: notification.body,
...(notification.imageUrl && { imageUrl: notification.imageUrl })
},
data: {
...data,
timestamp: new Date().toISOString()
},
android: {
notification: {
icon: 'ic_notification',
color: '#FF5722',
sound: 'default',
priority: 'high'
}
},
apns: {
payload: {
aps: {
sound: 'default',
badge: 1
}
}
}
};
const response = await messaging.send(message);
return {
success: true,
messageId: response,
token: token
};
} catch (error) {
console.error('Push notification gönderme hatası:', error);
// Token geçersizse, bu bilgiyi döndür
if (error.code === 'messaging/registration-token-not-registered' ||
error.code === 'messaging/invalid-registration-token') {
return {
success: false,
error: 'Invalid token',
invalidToken: true,
token: token
};
}
return {
success: false,
error: error.message,
token: token
};
}
};
/**
* Birden fazla cihaza push notification gönder
* @param {string[]} tokens - Device token'ları
* @param {object} notification - Notification objesi
* @param {object} data - Ek veri
* @returns {Promise<object>} Gönderim sonucu
*/
const sendToMultipleDevices = async (tokens, notification, data = {}) => {
const messaging = getMessaging();
if (!messaging) {
return { success: false, error: 'Firebase Messaging kullanılamıyor' };
}
if (!tokens || tokens.length === 0) {
return { success: false, error: 'Token listesi boş' };
}
try {
const message = {
notification: {
title: notification.title,
body: notification.body,
...(notification.imageUrl && { imageUrl: notification.imageUrl })
},
data: {
...data,
timestamp: new Date().toISOString()
},
android: {
notification: {
icon: 'ic_notification',
color: '#FF5722',
sound: 'default',
priority: 'high'
}
},
apns: {
payload: {
aps: {
sound: 'default',
badge: 1
}
}
},
tokens: tokens
};
const response = await messaging.sendMulticast(message);
// Başarısız token'ları topla
const failedTokens = [];
const invalidTokens = [];
response.responses.forEach((resp, idx) => {
if (!resp.success) {
const token = tokens[idx];
failedTokens.push({ token, error: resp.error?.message });
if (resp.error?.code === 'messaging/registration-token-not-registered' ||
resp.error?.code === 'messaging/invalid-registration-token') {
invalidTokens.push(token);
}
}
});
return {
success: response.successCount > 0,
successCount: response.successCount,
failureCount: response.failureCount,
failedTokens: failedTokens,
invalidTokens: invalidTokens
};
} catch (error) {
console.error('Toplu push notification gönderme hatası:', error);
return {
success: false,
error: error.message
};
}
};
/**
* Topic'e push notification gönder
* @param {string} topic - Topic adı
* @param {object} notification - Notification objesi
* @param {object} data - Ek veri
* @returns {Promise<object>} Gönderim sonucu
*/
const sendToTopic = async (topic, notification, data = {}) => {
const messaging = getMessaging();
if (!messaging) {
return { success: false, error: 'Firebase Messaging kullanılamıyor' };
}
try {
const message = {
topic: topic,
notification: {
title: notification.title,
body: notification.body,
...(notification.imageUrl && { imageUrl: notification.imageUrl })
},
data: {
...data,
timestamp: new Date().toISOString()
},
android: {
notification: {
icon: 'ic_notification',
color: '#FF5722',
sound: 'default',
priority: 'high'
}
},
apns: {
payload: {
aps: {
sound: 'default',
badge: 1
}
}
}
};
const response = await messaging.send(message);
return {
success: true,
messageId: response,
topic: topic
};
} catch (error) {
console.error('Topic push notification gönderme hatası:', error);
return {
success: false,
error: error.message,
topic: topic
};
}
};
/**
* Cihazı topic'e abone et
* @param {string[]} tokens - Device token'ları
* @param {string} topic - Topic adı
* @returns {Promise<object>} Abonelik sonucu
*/
const subscribeToTopic = async (tokens, topic) => {
const messaging = getMessaging();
if (!messaging) {
return { success: false, error: 'Firebase Messaging kullanılamıyor' };
}
try {
const response = await messaging.subscribeToTopic(tokens, topic);
return {
success: response.successCount > 0,
successCount: response.successCount,
failureCount: response.failureCount,
errors: response.errors
};
} catch (error) {
console.error('Topic abonelik hatası:', error);
return {
success: false,
error: error.message
};
}
};
/**
* Cihazın topic aboneliğini iptal et
* @param {string[]} tokens - Device token'ları
* @param {string} topic - Topic adı
* @returns {Promise<object>} Abonelik iptal sonucu
*/
const unsubscribeFromTopic = async (tokens, topic) => {
const messaging = getMessaging();
if (!messaging) {
return { success: false, error: 'Firebase Messaging kullanılamıyor' };
}
try {
const response = await messaging.unsubscribeFromTopic(tokens, topic);
return {
success: response.successCount > 0,
successCount: response.successCount,
failureCount: response.failureCount,
errors: response.errors
};
} catch (error) {
console.error('Topic abonelik iptal hatası:', error);
return {
success: false,
error: error.message
};
}
};
/**
* Firebase durumunu kontrol et
* @returns {object} Firebase durum bilgisi
*/
const getStatus = () => {
return {
initialized: !!firebaseApp,
messaging: !!getMessaging(),
projectId: firebaseApp?.options?.projectId || null
};
};
module.exports = {
initializeFirebase,
getMessaging,
sendToDevice,
sendToMultipleDevices,
sendToTopic,
subscribeToTopic,
unsubscribeFromTopic,
getStatus
};