Skip to content
This repository has been archived by the owner on Oct 20, 2024. It is now read-only.

Commit

Permalink
feat: ✨ user 엔터티 fcmToken 컬럼 추가, 로그인 시 토큰 최신화 구현 (#64)
Browse files Browse the repository at this point in the history
* Initial commit

* Feat/#1 oauth2login (#3)

* feat: User 엔터티 생성

* feat: jwt 버전 11->12, JWTUtil 생성

* feat: JWTFilter(JwtAuthenticationFilter) 등록

* feat: kakao 로그인 구현

* docs: swagger 태그(Authorization) 추가 (#5)

* feat: User 엔터티 생성

* feat: jwt 버전 11->12, JWTUtil 생성

* feat: JWTFilter(JwtAuthenticationFilter) 등록

* feat: kakao 로그인 구현

* docs: swagger 태그(Authorization) 추가

* feat: accesstoken 테스트를 위한 test login 생성 (#9)

* feat: User 엔티티에 상속 (#12)

* feat: BaseEntity 생성

* feat: User 엔티티에 상속

* feat: 일기 생성 기능 구현 (#14)

* feat: accesstoken 테스트를 위한 test login 생성

* feat: 일기 생성 기능 구현

* hotfix: ci 에러 수정 (#16)

* feat: accesstoken 테스트를 위한 test login 생성

* feat: 일기 생성 기능 구현

* hotfix: ci 에러 수정

* fix: OIDC 카카오 로그인 nullPointerException 해결

* feat: 닉네임 설정 기능 구현 (#21)

* feat: 일기 수정 기능 구현 (#25)

* feat: 일기에 감정 컬럼 추가

* feat: 일기 수정 기능 구현

* feat: 일기 삭제 기능 구현 (#27)

* feat: 일기에 감정 컬럼 추가

* feat: 일기 수정 기능 구현

* feat: 일기 삭제 기능 구현

* feat: 일기 감정 분석 기능 구현 (#31)

* feat: 감정 저장 기능 구현 (#33)

* feat: 일기 감정 분석 기능 구현

* feat: 감정 저장 기능 구현

* fix: 🐛 감정 저장 안되던 오류 수정 (#35)

* feat: 일기 감정 분석 기능 구현

* feat: 감정 저장 기능 구현

* fix: 🐛 감정 저장 안되던 오류 수정

* hotfix: 🚑 서버 꺼짐 현상 해결 (#37)

* feat: 일기 감정 분석 기능 구현

* feat: 감정 저장 기능 구현

* fix: 🐛 감정 저장 안되던 오류 수정

* hotfix: 🚑 서버 꺼짐 현상 해결

* feat: ✨ 홈 화면 조회 기능 구현 (#41)

* feat: ✨ 회원가입 완료 여부 필드 추가 (#44)

* feat: ✨ 일기 상세 조회 구현 (#47)

* feat: ✨ 기간 별 감정 통계 조회 기능 구현 (#50)

* feat: ✨ 일기 내용 검색 기능 구현 (#52)

* feat: ✨ 감정 별 일기 조회 (#54)

* feat: ✨ 월 별 일기 조회 기능 구현 (#59)

* ci: ⚡ workflow 수정 (#61)

* ci: ⚡ workflow 수정

* ci: ⚡ workflow 수정

* feat: ✨ user 엔터티 fcmToken 컬럼 추가, 로그인 시 토큰 최신화 구현 (#63)

* ci: ⚡ workflow 수정

* ci: ⚡ workflow 수정

* feat: ✨ fcm 토큰 알림 기능 구현

* feat: ✨ user 엔터티 fcmToken 컬럼 추가, 로그인 시 토큰 최신화 구현
  • Loading branch information
LEEJaeHyeok97 authored Jul 31, 2024
1 parent 8e0294b commit 56b016e
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 1 deletion.
5 changes: 5 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ dependencies {
implementation 'com.auth0:java-jwt:3.18.2'
implementation 'com.auth0:jwks-rsa:0.20.0'

//fcm
implementation 'com.google.firebase:firebase-admin:6.8.1'
implementation group: 'com.squareup.okhttp3', name: 'okhttp', version: '4.2.2'
implementation 'com.google.guava:guava:30.0-jre'

//s3 bucket
implementation platform('com.amazonaws:aws-java-sdk-bom:1.11.1000')
implementation 'com.amazonaws:aws-java-sdk-s3'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,11 @@ public NicknameRes updateNickname(UserPrincipal userPrincipal, String nickname)

return nicknameRes;
}

@Transactional
public void updateFcmToken(Long id, String fcmToken) {
User user = userRepository.findById(id)
.orElseThrow(EntityNotFoundException::new);
user.updateFcmToken(fcmToken);
}
}
3 changes: 2 additions & 1 deletion src/main/java/com/aidiary/domain/auth/dto/IdTokenReq.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
@Builder
public record IdTokenReq(
String idToken,
String provider
String provider,
String fcmToken
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ public ResponseCustom<AuthRes> login(@RequestBody IdTokenReq idTokenReq) {
User user = userRepository.findByProviderId(providerId)
.orElseThrow(EntityNotFoundException::new);

authService.updateFcmToken(user.getId(), idTokenReq.fcmToken());

AuthRes authRes = AuthRes.builder()
.accessToken(accessToken)
.isRegistered(user.isRegistered())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.aidiary.domain.notification.application;

import com.aidiary.domain.notification.dto.FcmMessage;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.auth.oauth2.GoogleCredentials;
import lombok.RequiredArgsConstructor;
import okhttp3.*;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.List;

@Service
@RequiredArgsConstructor
@Transactional
public class FcmService {

private final String API_URL = "https://fcm.googleapis.com/v1/projects/" +
"nabi-ffce7/messages:send";
private final ObjectMapper objectMapper;

@Transactional
public void sendMessageTo(String targetToken, String title, String body) throws IOException {
String message = makeMessage(targetToken, title, body);

OkHttpClient client = new OkHttpClient();
RequestBody requestBody = RequestBody.create(message,
MediaType.get("application/json; charset=utf-8"));
Request request = new Request.Builder()
.url(API_URL)
.post(requestBody)
.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + getAccessToken())
.addHeader(HttpHeaders.CONTENT_TYPE, "application/json; UTF-8")
.build();

Response response = client.newCall(request).execute();

System.out.println(response.body().string());
}

private String makeMessage(String targetToken, String title, String body) throws JsonParseException, JsonProcessingException {
FcmMessage fcmMessage = FcmMessage.builder()
.message(FcmMessage.Msg.builder()
.token(targetToken)
.notification(FcmMessage.Notification.builder()
.title(title)
.body(body)
.image(null)
.build()
).build()).validateOnly(false).build();

return objectMapper.writeValueAsString(fcmMessage);
}

private String getAccessToken() throws IOException {
String firebaseConfigPath = "firebase/firebase_service_key.json";

GoogleCredentials googleCredentials = GoogleCredentials
.fromStream(new ClassPathResource(firebaseConfigPath).getInputStream())
.createScoped(List.of("https://www.googleapis.com/auth/cloud-platform"));

googleCredentials.refreshIfExpired();
return googleCredentials.getAccessToken().getTokenValue();
}

}
28 changes: 28 additions & 0 deletions src/main/java/com/aidiary/domain/notification/dto/FcmMessage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.aidiary.domain.notification.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@Builder
public record FcmMessage(
boolean validateOnly,
Msg message
) {
@Builder
@AllArgsConstructor
@Getter
public static class Msg {
private Notification notification;
private String token;
}

@Builder
@AllArgsConstructor
@Getter
public static class Notification {
private String title;
private String body;
private String image;
}
}
8 changes: 8 additions & 0 deletions src/main/java/com/aidiary/domain/notification/dto/FcmReq.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.aidiary.domain.notification.dto;

public record FcmReq(
String targetToken,
String title,
String body
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.aidiary.domain.notification.presentation;

import com.aidiary.domain.notification.application.FcmService;
import com.aidiary.domain.notification.dto.FcmReq;
import com.aidiary.global.payload.ResponseCustom;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

@RestController
@RequiredArgsConstructor
@RequestMapping("/fcm")
public class NotificationController {

private final FcmService fcmService;


@PostMapping
public ResponseCustom<?> pushMessage(@RequestBody FcmReq fcmReq) throws IOException {
System.out.println(fcmReq.targetToken() + " "
+ fcmReq.title() + " " + fcmReq.body());

fcmService.sendMessageTo(
fcmReq.targetToken(),
fcmReq.title(),
fcmReq.body()
);

return ResponseCustom.OK("Message is pushed");
}
}
6 changes: 6 additions & 0 deletions src/main/java/com/aidiary/domain/user/domain/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public class User extends BaseEntity {

private boolean isRegistered;

private String fcmToken;


@Builder
public User(String nickname, String username, String email, String role, String provider, String providerId) {
Expand All @@ -49,4 +51,8 @@ public void updateNickname(String nickname) {
public void updateIsRegistered() {
this.isRegistered = true;
}

public void updateFcmToken(String fcmToken) {
this.fcmToken = fcmToken;
}
}

0 comments on commit 56b016e

Please sign in to comment.