In this Previous tutorial we have seen example FCM Push Notification , In this tutorial we will see how to do grouping of messages using FCM Topic Messaging .
FCM Topic Messaging is based on the publish/subscribe model, FCM topic messaging allows you to send a message to segment or group of device that have subscribed for a particular topic , while composing push notification when you add topic message FCM handles routing and delivering the message reliably to the right devices .
For Example , Let say news app which sends news notification for 3 different languages (English , Spanish , Russian ) , users can opt for language of his interest by subscribing from the client and while composing notification when you select the particular language only these users we will get message who have subscribed for that topic .
- One app instance can be subscribed to no more than 2000 topics.
- The frequency of new subscriptions is rate-limited per project.
- If you send too many subscription requests in a short period of time, FCM servers will respond with a 429 RESOURCE_EXHAUSTED ("quota exceeded") response. Retry with exponential backoff.
1. Storing Data In App's SharedPreference
To Store the topic name with status using sharedPreference .
file : PreferenceManager.kt
package com.tutorialsbuzz.fcmdemo class PreferenceManager internal constructor(context: Context) { private val mPrefs: SharedPreferences init { mPrefs = context.getSharedPreferences(PREFERENCES, 0) } companion object { private const val PREFERENCES = "settings" private var mPreferenceManager: PreferenceManager? = null fun getInstance(context: Context): PreferenceManager? { if (mPreferenceManager == null) { mPreferenceManager = PreferenceManager(context) } return mPreferenceManager } } fun getStoredJSONOptimization(): List<Model>? { val gson = Gson() val response = mPrefs.getString( Name.JSON_DATA, null ) ?: return null return gson.fromJson(response, Array<Model>::class.java).toList() } fun storeJSONOptimization(value: String?) { mPrefs.edit().putString( Name.JSON_DATA, value ).apply() } object Name { const val JSON_DATA = "JSON_DATA" } }
1. XML Layout For RecyclerView Row Item
file : row_item.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/subscribeLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="10dp"> <TextView android:id="@+id/subscribeLabel" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginStart="5dp" android:layout_marginLeft="5dp" android:layout_marginTop="20dp" android:layout_marginBottom="20dp" android:layout_weight="1" android:text="English" android:textSize="22sp" /> <ProgressBar android:id="@+id/progressBar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginRight="10dp" android:visibility="gone" /> <TextView android:id="@+id/subscribe" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginTop="20dp" android:layout_marginEnd="10dp" android:layout_marginRight="10dp" android:layout_marginBottom="20dp" android:text="@string/subscribe" android:textSize="16sp" android:textStyle="bold" /> </RelativeLayout>
1. Adapter
Adapter For RecyclerView For displaying list of topics user subscribed and unsubscribed and updating the status when user updates the status .
file : SubscriptionAdapter.kt
package com.tutorialsbuzz.fcmdemo class SubscriptionAdapter(val modelList: List<Model>, val context: Context) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { val itemViewHolder = (holder as ViewHolder) itemViewHolder.bind(modelList.get(position)); } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { val layoutInflater = LayoutInflater.from(parent.context) return ViewHolder(layoutInflater.inflate(R.layout.row_item, parent, false)) } override fun getItemCount(): Int { return modelList.size; } lateinit var mClickListener: ClickListener fun setOnItemClickListener(aClickListener: ClickListener) { mClickListener = aClickListener } interface ClickListener { fun onClick(pos: Int, aView: View) } inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener { fun bind(model: Model): Unit { itemView.subscribeLabel.text = "${(adapterPosition + 1)} ) ${model.name}" if (model.status) { itemView.subscribe.setText(R.string.subscribed) itemView.subscribe.setTextColor(ContextCompat.getColor(context, R.color.subscribed)) } else { itemView.subscribe.setText(R.string.subscribe) itemView.subscribe.setTextColor(ContextCompat.getColor(context, R.color.subscribe)) } itemView.subscribe.visibility = View.VISIBLE itemView.progressBar.visibility = View.GONE itemView.subscribe.setOnClickListener(this) } override fun onClick(view: View?) { if (view?.id == itemView.subscribe.id) { itemView.subscribe.visibility = View.GONE itemView.progressBar.visibility = View.VISIBLE mClickListener.onClick(adapterPosition, itemView) } } } }
1. XML Layout for Activity
file : activity_subscribe.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/subscriptionList" android:layout_width="match_parent" android:layout_height="wrap_content" />
1. Activity
Subscribe the client app to a topic.
// subscribe for notification topic fun subscribeToTopics(topic: String, position: Int) { FirebaseMessaging.getInstance().subscribeToTopic(topic) .addOnCompleteListener { task -> //String msg = getString(R.string.msg_subscribed); if (task.isSuccessful) { //Topic Subscribed Succesfully Todo Task } } }
UnSubscribe the client app to a topic.
// Unsubscribe for notification topic fun UnSubscribeToTopics(topic: String, position: Int) { FirebaseMessaging.getInstance().unsubscribeFromTopic(topic) .addOnCompleteListener { task -> //String msg = getString(R.string.msg_subscribed); if (task.isSuccessful) { //Topic Unsubscribed Succesfully Todo Task } } }
Complete code for Subscribe Notification Activity
package com.tutorialsbuzz.fcmdemo class SubscribeNotificationTopicsActivity : AppCompatActivity() { private lateinit var adapter: SubscriptionAdapter override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_subscribe) subscriptionList.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false) subscriptionList.addItemDecoration(SimpleDividerItemDecoration(this)) adapter = SubscriptionAdapter(readFromAsset(), this) subscriptionList.adapter = adapter adapter.setOnItemClickListener(object : SubscriptionAdapter.ClickListener { override fun onClick(pos: Int, aView: View) { // status false user not subscribed if (!adapter.modelList.get(pos).status) { subscribeToTopics(adapter.modelList.get(pos).name, pos) } else { UnSubscribeToTopics(adapter.modelList.get(pos).name, pos) } } }) } fun updateList(position: Int, status: Boolean) { adapter.modelList.get(position).status = status adapter.notifyItemChanged(position) val preferenceManager = PreferenceManager.getInstance(this@SubscribeNotificationTopicsActivity) preferenceManager?.storeJSONOptimization(Gson().toJson(adapter.modelList)) } // subscribe for notification topic fun subscribeToTopics(topic: String, position: Int) { FirebaseMessaging.getInstance().subscribeToTopic(topic) .addOnCompleteListener { task -> //String msg = getString(R.string.msg_subscribed); if (task.isSuccessful) { updateList(position, true) showToast("Subscribe To " + topic) } } } // Unsubscribe for notification topic fun UnSubscribeToTopics(topic: String, position: Int) { FirebaseMessaging.getInstance().unsubscribeFromTopic(topic) .addOnCompleteListener { task -> //String msg = getString(R.string.msg_subscribed); if (task.isSuccessful) { updateList(position, false) showToast("UnSubscribed For " + topic) } } } fun showToast(msg: String) { Toast.makeText( this@SubscribeNotificationTopicsActivity, msg, Toast.LENGTH_SHORT ).show() } private fun readFromAsset(): List<Model> { /** Find Code for Read from Asset from Below Download Code Link**/ } }
Composing Notification From Firebase Console
No comments:
Post a Comment