-
Notifications
You must be signed in to change notification settings - Fork 45
Firebase setup #183
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Firebase setup #183
Changes from all commits
81fc4b0
5ccc278
73ee64c
21593ef
b7eeeb9
482f441
7d7340b
0563e98
75e5f18
f33b2ae
f864587
dbcc0ab
067bf71
a4236c2
adba41e
5f382bf
9a94bee
d288ed1
c16bf0c
0b7922e
1e4eea6
0698e6b
08fd1b8
b807305
cd4a707
3f5a727
72715a7
121928c
396359d
0e24515
70a4256
8df1a0f
7222cbd
ede0339
e3a177e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
1.8 | ||
17.0 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package com.iemr.common.config.firebase; | ||
|
||
import com.google.auth.oauth2.GoogleCredentials; | ||
import com.google.firebase.FirebaseApp; | ||
import com.google.firebase.FirebaseOptions; | ||
import com.google.firebase.messaging.FirebaseMessaging; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.core.io.ClassPathResource; | ||
|
||
import java.io.ByteArrayInputStream; | ||
import java.io.IOException; | ||
import java.util.Base64; | ||
|
||
@Configuration | ||
public class FirebaseMessagingConfig { | ||
|
||
@Value("${firebase.enabled:false}") | ||
private boolean firebaseEnabled; | ||
|
||
@Value("${firebase.credential-file:}") | ||
private String firebaseCredentialFile; | ||
|
||
@Value("${firebase.credential-base64:}") | ||
private String firebaseCredentialBase64; | ||
|
||
@Bean | ||
public FirebaseMessaging firebaseMessaging() throws IOException { | ||
if (!firebaseEnabled) { | ||
throw new IllegalStateException("Firebase is disabled"); | ||
} | ||
|
||
GoogleCredentials credentials; | ||
|
||
if (!firebaseCredentialBase64.isBlank()) { | ||
byte[] decoded = Base64.getDecoder().decode(firebaseCredentialBase64); | ||
credentials = GoogleCredentials.fromStream(new ByteArrayInputStream(decoded)); | ||
} else if (!firebaseCredentialFile.isBlank()) { | ||
credentials = GoogleCredentials.fromStream( | ||
new ClassPathResource(firebaseCredentialFile).getInputStream() | ||
); | ||
} else { | ||
throw new IllegalStateException("No Firebase credentials provided"); | ||
} | ||
|
||
FirebaseOptions options = FirebaseOptions.builder() | ||
.setCredentials(credentials) | ||
.build(); | ||
|
||
FirebaseApp firebaseApp = FirebaseApp.getApps().isEmpty() | ||
? FirebaseApp.initializeApp(options) | ||
: FirebaseApp.getInstance(); | ||
|
||
return FirebaseMessaging.getInstance(firebaseApp); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package com.iemr.common.controller.firebaseNotification; | ||
|
||
import com.iemr.common.model.notification.NotificationMessage; | ||
import com.iemr.common.service.firebaseNotification.FirebaseNotificationService; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
@RestController | ||
@RequestMapping(value= "/firebaseNotification",headers = "Authorization") | ||
public class FirebaseNotificationController { | ||
final Logger logger = LoggerFactory.getLogger(this.getClass().getName()); | ||
|
||
@Autowired | ||
FirebaseNotificationService firebaseNotificationService; | ||
|
||
@RequestMapping(value = "sendNotification",method = RequestMethod.POST) | ||
public String sendNotificationByToken(@RequestBody NotificationMessage notificationMessage){ | ||
return firebaseNotificationService.sendNotification(notificationMessage); | ||
} | ||
Comment on lines
+18
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. π οΈ Refactor suggestion Method name inconsistent with implementation. The method is named Consider these improvements: @RequestMapping(value = "sendNotification",method = RequestMethod.POST)
-public String sendNotificationByToken(@RequestBody NotificationMessage notificationMessage){
- return firebaseNotificationService.sendNotification(notificationMessage);
+public ResponseEntity<String> sendNotificationByToken(@RequestBody @Valid NotificationMessage notificationMessage){
+ try {
+ String result = firebaseNotificationService.sendNotification(notificationMessage);
+ return ResponseEntity.ok(result);
+ } catch (Exception e) {
+ logger.error("Error sending notification: ", e);
+ return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
+ .body("Failed to send notification: " + e.getMessage());
+ }
} Don't forget to add the required imports: import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import javax.validation.Valid; |
||
|
||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
π‘ Verification agent
π§© Analysis chain
Missing service implementation details.
I cannot find the implementation of
FirebaseNotificationService
that this controller depends on. The service would need to handle the actual Firebase messaging operations.π Web query:
π‘ Result:
To implement Firebase Cloud Messaging (FCM) effectively on the server-side with Java, follow these best practices:
Token Management
Store tokens securely with timestamps using Firestore or your backend database. Track token freshness by updating timestamps regularly (e.g., monthly) to identify stale tokens[4][5].
Refresh tokens periodically using WorkManager to ensure validity[4]:
Prune stale tokens by checking timestamps. Remove tokens older than a defined threshold (e.g., 30 days)[5]:
Message Handling
Use the Firebase Admin SDK for built-in authentication and message validation[1][3]:
Prefer
data
messages for app-controlled behavior. Usenotification
messages only for UI alerts[7]:Limit message size to under 4,000 bytes and avoid sending redundant keys like
from
ormessage_id
[8].Error Handling and Retries
Check for failures in multicast sends and log invalid tokens[1]:
Implement exponential backoff for retries. The Admin SDK handles this automatically, but custom implementations should wait at least 10 seconds between attempts[8].
Scaling and Performance
Security
serviceAccountKey.json
) using environment variables or secret management tools[3].By following these practices, you ensure efficient, reliable, and scalable FCM integration in Java server environments[1][3][5][8].
Citations:
Action Required: Implement FirebaseNotificationService
The controller currently delegates to
FirebaseNotificationService
without any visible implementation details. Based on best practices for Firebase Cloud Messaging with Java, please ensure that the service:serviceAccountKey.json
) are protected via environment variables or secret management tools.Addressing these points will strengthen the reliability and security of FCM operations.