| Crates.io | fcm_receiver_rs |
| lib.rs | fcm_receiver_rs |
| version | 0.1.1 |
| created_at | 2025-09-20 15:25:02.349402+00 |
| updated_at | 2025-09-20 15:28:20.968947+00 |
| description | A Rust library that simulates an Android device to receive Firebase Cloud Messaging (FCM) notifications. |
| homepage | |
| repository | https://github.com/agusibrahim/fcm_receiver.rs |
| max_upload_size | |
| id | 1847869 |
| size | 197,942 |
A Rust library that simulates an Android device to receive Firebase Cloud Messaging (FCM) notifications. This library allows your application to behave like a real device when receiving push notifications from FCM servers.
This library emulates Android device functionality in the FCM ecosystem, including the ability to:
The FCM/GCM tokens generated can be used to send notifications to this simulated device, just like sending notifications to a real Android device.
Important: This library implements FCM protobuf messages manually without using the protobuf library. While FCM communication uses protobuf over socket connections, this library:
This approach keeps the library lightweight and avoids the complexity of protobuf compilation while maintaining full compatibility with FCM protocols.
For detailed technical information about the FCM protocol implementation, see TECHNICAL.md.
The TECHNICAL.md document provides:
This technical guide is essential for understanding how the library works internally and can help with debugging or extending the functionality.
For Firebase projects with protection/restrictions, you need to properly configure the Android package information. This is crucial when Firebase is configured to only accept connections from specific Android packages.
use fcm_receiver_rs::client::{FcmClient, AndroidApp};
fn main() -> Result<()> {
let mut client = FcmClient::new(
"YOUR_API_KEY".to_string(),
"YOUR_APP_ID".to_string(),
"YOUR_PROJECT_ID".to_string(),
)?;
// Configure Android package information
client.android_app = Some(AndroidApp {
gcm_sender_id: "123456789".to_string(), // Your sender id
android_package: "com.example.app".to_string(), // Your Android package name
android_package_cert: "YOUR_SHA1_SIGNATURE".to_string(), // SHA1 signature of your APK
});
// Continue with registration...
Ok(())
}
For testing purposes, you can use a SHA1 signature from a real APK or generate one:
# Get SHA1 from debug keystore (for development)
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
# Or use a known SHA1 from a production app
# Example: "2E:4A:3B:8C:1D:9E:F5:A0:B6:C7:D8:E9:F0:A1:B2:C3:D4:E5:F6"
# Just passing: "2E4A3B8C1D9EF5A0B6C7D8E9F0A1B2C3D4E5F6"
Add to your Cargo.toml:
[dependencies]
fcm_receiver_rs = { path = "./fcm_receiver_rs" }
use fcm_receiver_rs::client::FcmClient;
use fcm_receiver_rs::Result;
use std::sync::Arc;
fn main() -> Result<()> {
// Initialize FCM client
let mut client = FcmClient::new(
"YOUR_API_KEY".to_string(),
"YOUR_APP_ID".to_string(),
"YOUR_PROJECT_ID".to_string(),
)?;
// Configure Android package for Firebase compatibility (optional)
client.android_app = Some(fcm_receiver_rs::client::AndroidApp {
gcm_sender_id: "123456789".to_string(),
android_package: "com.example.app".to_string(),
android_package_cert: "YOUR_SHA1_SIGNATURE".to_string(),
});
// Set up notification handler
client.on_data_message = Some(Arc::new(|payload| {
let text = String::from_utf8_lossy(&payload);
println!("Received notification: {}", text);
}));
// Generate encryption keys
let (private_key_b64, auth_secret_b64) = client.create_new_keys()?;
client.load_keys(&private_key_b64, &auth_secret_b64)?;
// Register as device and get tokens
let (fcm_token, gcm_token, android_id, security_token) = client.register()?;
println!("Registration successful!");
println!("FCM Token: {}", fcm_token);
println!("GCM Token: {}", gcm_token);
println!("Android ID: {}", android_id);
// Save tokens for server use
// These tokens can be used in FCM HTTP API v1
// Subscribe to topic
client.subscribe_to_topic("promotions")?;
// Start listening for notifications
client.start_listening()?;
Ok(())
}
The generated tokens can be used by servers to send notifications:
// Register device
let (fcm_token, gcm_token, android_id, security_token) = client.register()?;
// FCM Token can be used in FCM HTTP API v1
// Format: fcm_token can be used directly in FCM endpoints
println!("FCM Token for server: {}", fcm_token);
Subscribe and unsubscribe from topics like a real Android device:
// Subscribe to topics
client.subscribe_to_topic("news")?;
client.subscribe_to_topic("promotions")?;
// Unsubscribe from topics
client.unsubscribe_from_topic("old_topic")?;
After subscribing to topics, the device will receive notifications sent to those topics:
// Handler for decrypted notifications
client.on_data_message = Some(Arc::new(|payload| {
let text = String::from_utf8_lossy(&payload);
println!("Incoming notification: {}", text);
}));
// Handler for raw messages (for debugging)
client.on_raw_message = Some(Arc::new(|msg| {
println!("Raw message: {:?}", msg);
}));
The generated FCM tokens can be used on servers to send notifications. Example using curl:
# Send notification to simulated device
curl -X POST https://fcm.googleapis.com/v1/projects/YOUR_PROJECT_ID/messages:send \
-H "Authorization: Bearer YOUR_SERVER_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"message": {
"token": "FCM_TOKEN_FROM_SIMULATED_DEVICE",
"notification": {
"title": "Test Notification",
"body": "Hello from server!"
},
"data": {
"custom_data": "value"
}
}
}'
The topic subscription/unsubscription implementation in this library references the microg/GmsCore project, which is an open-source implementation of Google Play Services.
See the example/ directory for a complete implementation that includes:
Run the example:
cd example
cargo run
1:123456789:android:abc123)reqwest - HTTP clientserde - JSON serializationp256 - Elliptic curve cryptographyaes-gcm - AES encryptionbase64 - Base64 encoding/decodingNote: This library does NOT use protobuf as a dependency. All protobuf messages are implemented manually.
This project is licensed under the MIT License.