현재 사이드프로젝트에 채팅 기능이 포함되어 있고 채팅을 보내면 상대방에게 push notification을 보내기 위해 fcm과 node.js를 사용하고 있습니다. 여러가지 방법을 시도했지만 잘 되지 않앗습니다.
현재 큰 이슈는 두가지입니다.
1. 채팅을 보내면 상대방에게 알림이 가지않고 채팅을 보낸 당사자에게 알림이옴.
2. node.js에 데이터가 넘어오면 log를 찍게 햇지만 아무런 반응이 없음.
몇일째 시도햇지만 아직 많이 부족해서 잘해결이 되지 않네요 도와주세요 선배님들 :(
1.백엔드 서버 FcmServer.js
const express = require('express');
const admin = require('firebase-admin');
const fetch = require('node-fetch');
const { GoogleAuth } = require('google-auth-library');
var serviceAccount = require('C:\\Users\\mj\\workspace\\keys\\animal-1ccca-4006e714b863.json');
// Firebase 초기화
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL : "https://animal-1ccca.firebaseio.com"
});
const app = express();
app.use(express.json()); // for parsing application/json
// Google Auth 인스턴스 생성
const auth = new GoogleAuth({
keyFilename: 'C:\\Users\\mj\\workspace\\keys\\animal-1ccca-firebase-adminsdk-add7s-e0ed63689a.json',
scopes: ['https://fcm.googleapis.com/v1/projects/animal-1ccca/messages:send'],
});
// getAccessToken 함수 정의
async function getAccessToken() {
try {
const tokens = await auth.getAccessToken();
return tokens.access_token;
} catch (error) {
throw new Error('Failed to retrieve access token: ' + error);
}
}
// POST /sendNotification 라우트 추가.
// 이 라우트는 클라이언트가 메시지를 보낼 때 호출됩니다.
app.post('/sendNotification', async (req, res) => {
console.log('Recevied request :', req.body)
try {
// 요청 본문에서 필요한 데이터 추출
const { receiverUid, message, nickname } = req.body;
const db = admin.database();
const ref = db.ref('user/' + receiverUid);
// DB에서 수신자의 FCM 토큰 가져오기
ref.child('FCMToken').once('value', async (snapshot) => {
const token = snapshot.val();
console.log(token)
if (token) {
// FCM 토큰이 존재하면 FCM 메시지 보내기
const endpoint = 'https://fcm.googleapis.com/v1/projects/animal-1ccca/messages:send';
const messageBody = {
message: {
token,
notification: {
title : nickname,
body: message,
},
},
};
const accessToken = await getAccessToken();
const response = await fetch(endpoint, {
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(messageBody),
});
const data = await response.json();
if (response.ok) {
res.json({ success: true });
} else {
res.status(400).json({ error: 'Error sending FCM message', data });
}
} else {
// FCM 토큰이 존재하지 않는 경우 에러 반환
res.status(404).json({ error: 'Token not found' });
}
});
} catch (error) {
res.status(500).json({ error: error.toString() });
}
});
// 3000 포트에서 서버 시작
app.listen(3000, () => {
console.log('Server running on port 3000');
});
안드로이드 코드
https://lowly-reply-f9d.notion.site/1-29e5ff0cf5e94f84b823771d4688f6f4