Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,20 @@ private void askNotificationPermission() {
}
}
// [END ask_post_notifications]

private void registerFid() {
// [START register_fid]
// Trigger manual registration if auto-initialization is turned off.
// Consider calling this every time the app starts to guarantee sync status.
FirebaseMessaging.getInstance().register()
.addOnCompleteListener(this, task -> {
if (!task.isSuccessful()) {
// Registration failed. Consider retrying the registration with exponential backoff.
Log.w(TAG, "Failed to register with Firebase Cloud Messaging", task.getException());
}
// Success! The Firebase Installation ID can be used to target messages to this app
// instance and will be delivered asynchronously to your onRegistered() callback.
});
// [END register_fid]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,24 @@ public Result doWork() {
return Result.success();
}
}

// [START on_fid_registered]
/**
* There are three scenarios when `onRegistered` is called:
* 1) Every time a manual `register()` call finishes successfully
* 2) Whenever the FID is changed and the app is re-registered with FCM via the new FID
* 3) Automatically on the first app startup or routine sync when auto-initialization is enabled.
* Under #2, there are three scenarios when the existing FID is changed:
* A) App is restored to a new device
* B) User uninstalls/reinstalls the app
* C) User clears app data
*/
@Override
public void onRegistered(@NonNull String installationId) {
Log.d(TAG, "Registered installation ID: " + installationId);

// Send the Firebase Installation ID to your app server.
sendRegistrationToServer(installationId);
}
// [END on_fid_registered]
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.google.firebase.Firebase
import com.google.firebase.firestore.FieldValue
import com.google.firebase.firestore.firestore
import com.google.firebase.Firebase
import com.google.firebase.messaging.messaging
import com.google.firebase.messaging.remoteMessage
import kotlinx.coroutines.launch
Expand All @@ -20,135 +20,150 @@ import java.util.concurrent.atomic.AtomicInteger

class MainActivity : AppCompatActivity() {

companion object {
private const val TAG = "MainActivity"
private const val NOTIFICATION_REQUEST_CODE = 1234
}
companion object {
private const val TAG = "MainActivity"
private const val NOTIFICATION_REQUEST_CODE = 1234
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// [START handle_data_extras]
intent.extras?.let {
for (key in it.keySet()) {
val value = intent.extras?.get(key)
Log.d(TAG, "Key: $key Value: $value")
}
}
// [END handle_data_extras]
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// [START handle_data_extras]
intent.extras?.let {
for (key in it.keySet()) {
val value = intent.extras?.get(key)
Log.d(TAG, "Key: $key Value: $value")
}
}
// [END handle_data_extras]
}

fun runtimeEnableAutoInit() {
// [START fcm_runtime_enable_auto_init]
Firebase.messaging.isAutoInitEnabled = true
// [END fcm_runtime_enable_auto_init]
}
fun runtimeEnableAutoInit() {
// [START fcm_runtime_enable_auto_init]
Firebase.messaging.isAutoInitEnabled = true
// [END fcm_runtime_enable_auto_init]
}

fun deviceGroupUpstream() {
// [START fcm_device_group_upstream]
val to = "a_unique_key" // the notification key
val msgId = AtomicInteger()
Firebase.messaging.send(
remoteMessage(to) {
setMessageId(msgId.get().toString())
addData("hello", "world")
},
)
// [END fcm_device_group_upstream]
}
fun deviceGroupUpstream() {
// [START fcm_device_group_upstream]
val to = "a_unique_key" // the notification key
val msgId = AtomicInteger()
Firebase.messaging.send(
remoteMessage(to) {
setMessageId(msgId.get().toString())
addData("hello", "world")
},
)
// [END fcm_device_group_upstream]
}

fun sendUpstream() {
val SENDER_ID = "YOUR_SENDER_ID"
val messageId = 0 // Increment for each
// [START fcm_send_upstream]
val fm = Firebase.messaging
fm.send(
remoteMessage("$SENDER_ID@fcm.googleapis.com") {
setMessageId(messageId.toString())
addData("my_message", "Hello World")
addData("my_action", "SAY_HELLO")
},
)
// [END fcm_send_upstream]
}
fun sendUpstream() {
val SENDER_ID = "YOUR_SENDER_ID"
val messageId = 0 // Increment for each
// [START fcm_send_upstream]
val fm = Firebase.messaging
fm.send(
remoteMessage("$SENDER_ID@fcm.googleapis.com") {
setMessageId(messageId.toString())
addData("my_message", "Hello World")
addData("my_action", "SAY_HELLO")
},
)
// [END fcm_send_upstream]
}

fun subscribeTopics() {
// [START subscribe_topics]
Firebase.messaging.subscribeToTopic("weather")
.addOnCompleteListener { task ->
var msg = "Subscribed"
if (!task.isSuccessful) {
msg = "Subscribe failed"
}
Log.d(TAG, msg)
Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
}
// [END subscribe_topics]
}
fun subscribeTopics() {
// [START subscribe_topics]
Firebase.messaging.subscribeToTopic("weather")
.addOnCompleteListener { task ->
var msg = "Subscribed"
if (!task.isSuccessful) {
msg = "Subscribe failed"
}
Log.d(TAG, msg)
Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
}
// [END subscribe_topics]
}

fun logRegToken() {
// [START log_reg_token]
Firebase.messaging.getToken().addOnCompleteListener { task ->
if (!task.isSuccessful) {
Log.w(TAG, "Fetching FCM registration token failed", task.exception)
return@addOnCompleteListener
}
fun logRegToken() {
// [START log_reg_token]
Firebase.messaging.getToken().addOnCompleteListener { task ->
if (!task.isSuccessful) {
Log.w(TAG, "Fetching FCM registration token failed", task.exception)
return@addOnCompleteListener
}

// Get new FCM registration token
val token = task.result
// Get new FCM registration token
val token = task.result

// Log and toast
val msg = "FCM Registration token: $token"
Log.d(TAG, msg)
Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
}
// [END log_reg_token]
// Log and toast
val msg = "FCM Registration token: $token"
Log.d(TAG, msg)
Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
}
// [END log_reg_token]
}

// [START ask_post_notifications]
// Declare the launcher at the top of your Activity/Fragment:
private val requestPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission(),
) { isGranted: Boolean ->
if (isGranted) {
// FCM SDK (and your app) can post notifications.
} else {
// TODO: Inform user that that your app will not show notifications.
}
// [START ask_post_notifications]
// Declare the launcher at the top of your Activity/Fragment:
private val requestPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission(),
) { isGranted: Boolean ->
if (isGranted) {
// FCM SDK (and your app) can post notifications.
} else {
// TODO: Inform user that that your app will not show notifications.
}
}

private fun askNotificationPermission() {
// This is only necessary for API level >= 33 (TIRAMISU)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
PackageManager.PERMISSION_GRANTED
) {
// FCM SDK (and your app) can post notifications.
} else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
// TODO: display an educational UI explaining to the user the features that will be enabled
// by them granting the POST_NOTIFICATION permission. This UI should provide the user
// "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
// If the user selects "No thanks," allow the user to continue without notifications.
} else {
// Directly ask for the permission
requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
}
}
private fun askNotificationPermission() {
// This is only necessary for API level >= 33 (TIRAMISU)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
PackageManager.PERMISSION_GRANTED
) {
// FCM SDK (and your app) can post notifications.
} else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
// TODO: display an educational UI explaining to the user the features that will be enabled
// by them granting the POST_NOTIFICATION permission. This UI should provide the user
// "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
// If the user selects "No thanks," allow the user to continue without notifications.
} else {
// Directly ask for the permission
requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
}
}
// [END ask_post_notifications]

// [START get_store_token]
private suspend fun getAndStoreRegToken(): String {
val token = Firebase.messaging.token.await()
// 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).await()
return token
}
// [END ask_post_notifications]

// [START get_store_token]
private suspend fun getAndStoreRegToken(): String {
val token = Firebase.messaging.token.await()
// 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).await()
return token
}
// [END get_store_token]

private fun registerFid() {
// [START register_fid]
// Trigger manual registration if auto-initialization is turned off.
// Consider calling this every time the app starts to guarantee sync status.
FirebaseMessaging.getInstance().register()
.addOnCompleteListener(this) { task ->
if (!task.isSuccessful()) {
Log.w(TAG, "Failed to register with Firebase Cloud Messaging", task.exception)
}
// Success! The Firebase Installation ID can be used to target messages to this app
// instance and will be delivered asynchronously to your onRegistered() callback.
}
// [END register_fid]
}
// [END get_store_token]
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,23 @@ class MyFirebaseMessagingService : FirebaseMessagingService() {
return Result.success()
}
}

// [START on_fid_registered]
/**
* There are three scenarios when `onRegistered` is called:
* 1) Every time a manual `register()` call finishes successfully
* 2) Whenever the FID is changed and the app is re-registered with FCM via the new FID.
* 3) Automatically on the first app startup or routine sync when auto-initialization is enabled.
* Under #2, there are three scenarios when the existing FID is changed:
* A) App is restored to a new device
* B) User uninstalls/reinstalls the app
* C) User clears app data
*/
override fun onRegistered(installationId: String) {
Log.d(TAG, "Registered installation ID: $installationId")

// Send the Firebase Installation ID to your app server.
sendRegistrationToServer(installationId)
}
// [END on_fid_registered]
}
Loading