-
Notifications
You must be signed in to change notification settings - Fork 7.4k
sample implementation of registration tokens for FCM #1453
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
base: master
Are you sure you want to change the base?
Changes from 12 commits
fca8b50
32c4b65
88f4bf5
4ef6bba
61a1767
5692eb5
1ff3190
cf9f113
7f876a4
baa8132
defd24c
248b3e6
d9cd34b
8057452
0b77e46
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 | ||||
---|---|---|---|---|---|---|
|
@@ -3,6 +3,7 @@ package com.google.firebase.quickstart.fcm.kotlin | |||||
import android.Manifest | ||||||
import android.app.NotificationChannel | ||||||
import android.app.NotificationManager | ||||||
import android.content.Context | ||||||
import android.content.pm.PackageManager | ||||||
import android.os.Build | ||||||
import android.os.Bundle | ||||||
|
@@ -11,14 +12,23 @@ import android.widget.Toast | |||||
import androidx.activity.result.contract.ActivityResultContracts | ||||||
import androidx.appcompat.app.AppCompatActivity | ||||||
import androidx.core.content.ContextCompat | ||||||
import com.google.android.gms.tasks.OnCompleteListener | ||||||
import androidx.lifecycle.lifecycleScope | ||||||
import com.google.firebase.Timestamp | ||||||
import com.google.firebase.firestore.FieldValue | ||||||
import com.google.firebase.firestore.ktx.firestore | ||||||
import com.google.firebase.ktx.Firebase | ||||||
import com.google.firebase.messaging.ktx.messaging | ||||||
import com.google.firebase.quickstart.fcm.R | ||||||
import com.google.firebase.quickstart.fcm.databinding.ActivityMainBinding | ||||||
import kotlinx.coroutines.launch | ||||||
import kotlinx.coroutines.tasks.await | ||||||
import java.util.Calendar | ||||||
import java.util.Date | ||||||
|
||||||
class MainActivity : AppCompatActivity() { | ||||||
|
||||||
val IS_OPTIMIZE = true | ||||||
|
val IS_OPTIMIZE = true | |
private val IS_OPTIMIZE = true |
Outdated
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.
preferences.edit().putLong("lastDeviceRefreshDate", Date().time) | |
preferences.edit().putLong("lastDeviceRefreshDate", Date().time).apply() |
Outdated
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.
Don't forget to call apply:
preferences.edit().putLong("lastGlobalRefreshDate", lastDeviceRefresh.time) | |
preferences.edit().putLong("lastGlobalRefreshDate", lastDeviceRefresh.time).apply() |
Outdated
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.
preferences.edit().putLong("lastGlobalRefreshDate", updatedTime) | |
preferences.edit().putLong("lastGlobalRefreshDate", updatedTime).apply() |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -7,13 +7,19 @@ import android.content.Context | |||||
import android.content.Intent | ||||||
import android.media.RingtoneManager | ||||||
import android.os.Build | ||||||
import android.preference.PreferenceManager | ||||||
import android.util.Log | ||||||
import androidx.core.app.NotificationCompat | ||||||
import androidx.work.OneTimeWorkRequest | ||||||
import androidx.work.WorkManager | ||||||
import com.google.firebase.firestore.FieldValue | ||||||
import com.google.firebase.firestore.ktx.firestore | ||||||
import com.google.firebase.ktx.Firebase | ||||||
import com.google.firebase.messaging.FirebaseMessagingService | ||||||
import com.google.firebase.messaging.RemoteMessage | ||||||
import com.google.firebase.quickstart.fcm.R | ||||||
import java.util.* | ||||||
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. Avoid wildcard imports |
||||||
|
||||||
|
||||||
class MyFirebaseMessagingService : FirebaseMessagingService() { | ||||||
|
||||||
|
@@ -74,7 +80,7 @@ class MyFirebaseMessagingService : FirebaseMessagingService() { | |||||
// If you want to send messages to this application instance or | ||||||
// manage this apps subscriptions on the server side, send the | ||||||
// FCM registration token to your app server. | ||||||
sendRegistrationToServer(token) | ||||||
sendTokenToServer(token) | ||||||
} | ||||||
// [END on_new_token] | ||||||
|
||||||
|
@@ -103,9 +109,21 @@ class MyFirebaseMessagingService : FirebaseMessagingService() { | |||||
* | ||||||
* @param token The new token. | ||||||
*/ | ||||||
private fun sendRegistrationToServer(token: String?) { | ||||||
private fun sendTokenToServer(token: String?) { | ||||||
// TODO: Implement this method to send token to your app server. | ||||||
Log.d(TAG, "sendRegistrationTokenToServer($token)") | ||||||
// Add token and timestamp to Firestore for this user | ||||||
val deviceToken = hashMapOf( | ||||||
"token" to token, | ||||||
"timestamp" to FieldValue.serverTimestamp(), | ||||||
) | ||||||
|
||||||
// Get user ID from Firebase Auth or your own server | ||||||
Firebase.firestore.collection("fcmTokens").document("myuserid") | ||||||
.set(deviceToken) | ||||||
|
||||||
// As an optimization, store today’s date in Android cache | ||||||
val preferences = this.getSharedPreferences("default", Context.MODE_PRIVATE) | ||||||
preferences.edit().putLong("lastDeviceRefreshDate", Date().time) | ||||||
|
preferences.edit().putLong("lastDeviceRefreshDate", Date().time) | |
preferences.edit().putLong("lastDeviceRefreshDate", Date().time).apply() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
'use strict'; | ||
|
||
const functions = require('firebase-functions'); | ||
const admin = require('firebase-admin'); | ||
|
||
admin.initializeApp(); | ||
|
||
const EXPIRATION_TIME = 1000 * 60 * 60 * 24 * 30; // 30 days | ||
|
||
/** | ||
* Scheduled function that runs once a month. It updates the last refresh date for | ||
* tokens so that a client can refresh the token if the last time it did so was | ||
* before the refresh date. | ||
*/ | ||
// [START refresh_date_scheduled_function] | ||
exports.scheduledFunction = functions.pubsub.schedule('0 0 1 * *').onRun((context) => { | ||
admin.firestore().doc('refresh/refreshDate').set({ lastRefreshDate : Date.now() }); | ||
}); | ||
// [END refresh_date_scheduled_function] | ||
|
||
/** | ||
* Scheduled function that runs once a day. It retrieves all stale tokens then | ||
* unsubscribes them from 'topic1' then deletes them. | ||
* | ||
* Note: weather is an example topic here. It is up to the developer to unsubscribe | ||
* all topics the token is subscribed to. | ||
*/ | ||
// [START remove_stale_tokens] | ||
exports.pruneTokens = functions.pubsub.schedule('every 24 hours').onRun(async (context) => { | ||
const staleTokensResult = await admin.firestore().collection('fcmTokens') | ||
.where("timestamp", "<", Date.now() - EXPIRATION_TIME) | ||
.get(); | ||
|
||
const staleTokens = staleTokensResult.docs.map(staleTokenDoc => staleTokenDoc.id); | ||
|
||
await admin.messaging().unsubscribeFromTopic(staleTokens, 'weather'); | ||
|
||
const deletePromises = []; | ||
for (const staleTokenDoc of staleTokensResult.docs) { | ||
deletePromises.push(staleTokenDoc.ref.delete()); | ||
} | ||
await Promise.all(deletePromises); | ||
}); | ||
// [END remove_stale_tokens] |
Uh oh!
There was an error while loading. Please reload this page.