Overview
Device tokens are required to send push notifications to user devices via Firebase Cloud Messaging. Users must register their device token with the Notifications service to receive push notifications.
Register Device Token
This endpoint is publicly accessible and does not require authentication. Device tokens should be registered when the user logs in or when the app starts.
Request Body
The unique identifier of the user
Type of user account. Must be one of:
Driver - Driver account
Passenger - Passenger account
Admin - Admin account
Company - Company account
Firebase Cloud Messaging (FCM) device token obtained from the mobile app or web app
Device platform. Common values:
Android - Android device
iOS - iOS device
Web - Web browser
Application version number (e.g., “1.2.3”)
Response
Whether the registration was successful
Human-readable message in Arabic describing the result
Example Request
curl -X POST https://api.masareagle.com/api/devices/register \
-H "Content-Type: application/json" \
-d '{
"userId": "driver_123",
"userType": "Driver",
"deviceToken": "fK8xY3zQT_u9qH2wR...",
"platform": "Android",
"appVersion": "1.5.0"
}'
{
"userId" : "driver_123" ,
"userType" : "Driver" ,
"deviceToken" : "fK8xY3zQT_u9qH2wRjLpN5vM1cX7bA4dE6gH8iJ0kL2mN4oP6qR8sT0uV2wX4yZ6" ,
"platform" : "Android" ,
"appVersion" : "1.5.0"
}
200 Success
400 Missing Fields
400 Invalid User Type
{
"success" : true ,
"message" : "تم تسجيل جهازك بنجاح"
}
Device Token Behavior
Add or Update
When registering a device token:
Existing Token for Same User : If the device token already exists for the user, it updates the record and marks it as active
Token Registered to Different User : If the token is registered to a different user, it transfers the token to the new user (removes from old user)
New Token : If it’s a new token, it creates a new registration record
Multiple Devices
Users can have multiple device tokens registered (e.g., phone, tablet, web browser). Notifications will be sent to all active devices.
Token States
Active : Token can receive notifications
Inactive : Token will not receive notifications (manually deactivated)
Activate All Device Tokens
Activate all device tokens for a user to resume receiving notifications.
Path Parameters
The user ID to activate tokens for
Response
{
"message" : "activated"
}
{
"message" : "userId is required"
}
Example Request
curl -X POST https://api.masareagle.com/api/device-tokens/driver_123/activate-all
Deactivate All Device Tokens
Deactivate all device tokens for a user to stop receiving notifications. Use this when a user logs out or disables notifications.
Path Parameters
The user ID to deactivate tokens for
Response
{
"message" : "deactivated"
}
{
{
"message" : "userId is required"
}
Example Request
curl -X POST https://api.masareagle.com/api/device-tokens/driver_123/deactivate-all
Database Schema
Device tokens are stored in the device_tokens table:
Field Type Description idstring Primary key (format: dt_{guid}) user_idstring User identifier user_typestring User type (Driver, Passenger, Admin, Company) device_tokenstring FCM device token platformstring Device platform (Android, iOS, Web) app_versionstring App version number is_activeboolean Whether token is active created_at_utcdatetime When token was first registered updated_at_utcdatetime When token was last updated
Implementation Guide
Android (Kotlin)
import com.google.firebase.messaging.FirebaseMessaging
// Get FCM token
FirebaseMessaging. getInstance ().token. addOnCompleteListener { task ->
if (task.isSuccessful) {
val token = task.result
registerDeviceToken (userId, userType, token, "Android" , BuildConfig.VERSION_NAME)
}
}
fun registerDeviceToken (userId: String , userType: String , token: String , platform: String , appVersion: String ) {
val request = RegisterDeviceTokenRequest (
userId = userId,
userType = userType,
deviceToken = token,
platform = platform,
appVersion = appVersion
)
api. registerDevice (request). enqueue ( object : Callback < RegisterDeviceTokenResponse > {
override fun onResponse (call: Call < RegisterDeviceTokenResponse >, response: Response < RegisterDeviceTokenResponse >) {
if (response.isSuccessful && response. body ()?.success == true ) {
Log. d ( "FCM" , "Device registered successfully" )
}
}
override fun onFailure (call: Call < RegisterDeviceTokenResponse >, t: Throwable ) {
Log. e ( "FCM" , "Failed to register device" , t)
}
})
}
iOS (Swift)
import FirebaseMessaging
// Get FCM token
Messaging. messaging (). token { token, error in
if let error = error {
print ( "Error fetching FCM token: \( error ) " )
} else if let token = token {
registerDeviceToken ( userId : userId, userType : userType, token : token, platform : "iOS" , appVersion : appVersion)
}
}
func registerDeviceToken ( userId : String , userType : String , token : String , platform : String , appVersion : String ) {
let request = RegisterDeviceTokenRequest (
userId : userId,
userType : userType,
deviceToken : token,
platform : platform,
appVersion : appVersion
)
APIClient. shared . registerDevice (request) { result in
switch result {
case . success ( let response) :
if response.success {
print ( "Device registered successfully" )
}
case . failure ( let error) :
print ( "Failed to register device: \( error ) " )
}
}
}
Web (JavaScript)
import { getMessaging , getToken } from "firebase/messaging" ;
const messaging = getMessaging ();
// Request notification permission
Notification . requestPermission (). then (( permission ) => {
if ( permission === 'granted' ) {
// Get FCM token
getToken ( messaging , { vapidKey: 'YOUR_VAPID_KEY' })
. then (( token ) => {
registerDeviceToken ( userId , userType , token , 'Web' , appVersion );
})
. catch (( err ) => {
console . error ( 'Error getting FCM token:' , err );
});
}
});
async function registerDeviceToken ( userId , userType , token , platform , appVersion ) {
try {
const response = await fetch ( 'https://api.masareagle.com/api/devices/register' , {
method: 'POST' ,
headers: {
'Content-Type' : 'application/json' ,
},
body: JSON . stringify ({
userId ,
userType ,
deviceToken: token ,
platform ,
appVersion ,
}),
});
const data = await response . json ();
if ( data . success ) {
console . log ( 'Device registered successfully' );
}
} catch ( error ) {
console . error ( 'Failed to register device:' , error );
}
}
Common Use Cases
User Login
// Register device token after successful login
await loginUser ( email , password );
const fcmToken = await getFCMToken ();
await registerDeviceToken ( user . id , user . type , fcmToken , platform , appVersion );
User Logout
// Deactivate tokens when user logs out
await deactivateAllTokens ( user . id );
await logoutUser ();
Token Refresh
// Update token if it changes (rare but possible)
firebaseMessaging . onTokenRefresh ( async ( newToken ) => {
await registerDeviceToken ( user . id , user . type , newToken , platform , appVersion );
});
Enable/Disable Notifications
// User toggles notification settings
async function setNotificationsEnabled ( enabled ) {
if ( enabled ) {
await activateAllTokens ( userId );
} else {
await deactivateAllTokens ( userId );
}
}
Troubleshooting
No Notifications Received
Check Token Registration : Verify the device token is registered and active
Check Firebase Console : Ensure FCM is configured correctly
Check Notification History : Verify notifications are being saved to database
Check Device Permissions : Ensure app has notification permissions
Check Token Validity : FCM tokens can expire, re-register if needed
Multiple Devices Not Working
Each device needs its own unique FCM token
All tokens for a user should be registered separately
Verify all tokens are marked as active
Notifications Going to Wrong User
This can happen if a device token is reused
The system automatically transfers tokens between users
Ensure you deactivate tokens on logout
Security Considerations
Important Security Notes:
Device tokens are sensitive - treat them like passwords
Always use HTTPS when transmitting tokens
Deactivate tokens when users log out
Tokens should be device-specific, not shared
Regularly clean up inactive or expired tokens
Rate Limits
Device token registration endpoints have no strict rate limits, but excessive requests may be throttled:
Recommended: Register once per login session
Maximum: 100 requests per minute per user