مشخصات مقاله
-
1367
-
0.0
-
8123
-
0
-
0
آموزش Firebase Cloud Messaging (FCM) در Android
آموزش Firebase Cloud Messaging (FCM) در Android
به نظر می آید که Push notification ها جزء مهمی از برنامه های اندرویدی باشند. این notification ها به ما کمک می کنند تا کاربران را حفظ کرده، کاربران فعال را افزایش دهیم و... . برای اینکه به تمامی کاربران برنامه ی خودمان Push notification ارسال کنیم، می توانیم از Firebase Cloud Messaging (FCM) استفاده کنیم. همچنین با استفاده از FCM می توان خیلی سریع اطلاعاتی معمولی و ترویجی (promotional information) ارسال کرد.
امروز در این پست می خواهیم چگونگی استفاده از FCM در برنامه های اندرویدی را آموزش دهیم.
FCM چیست؟
FCM سرویسی است که توسط گوگل ارائه می شود. تعریف گوگل از این سرویس به این صورت است: "FCM راهکار پیام دهی چند پلتفرمی است که به شما این امکان را می دهد که با اطمینان و بدون هیچ هزینه ای پیام بدهید."
همانطور که بیان شد این سرویس رایگان بوده و در عین حال استفاده از آن آسان است. پش از این به جای این سرویس از سرویس Google Cloud Messaging (GCM) استفاده می کردیم. اما امروزه سرویس GCM منسوخ شده است. به همین دلیل بهتر است که تنها از سرویس FCM استفاده کنید.
انواع پیام ها
قبل از اینکه جلوتر برویم نیاز است انواع پیام هایی که با استفاده از FCM می توان ارسال کرد را بشناسیم.
- پیام های اعلانی (Notification Message) : این نوع از پیام به صورت خودکار برای کاربر نهایی نمایش داده می شود. در این پیام ها ما شاهد مجموعه ای پیش تعریف شده از مقادیر کلیدی دوتایی (key-value) هستیم. همچنین می توانیم با استفاده از data payload این مقادیر را به صورت شخصی ایجاد کنیم.
- پیام های داده ای (Data message) : به صورت پیش فرض این نوع از پیام ها برای کاربران نهایی نمیش داده نمی شوند. برای اینکه کاربران بتوانند این پیام ها را ببینند نیاز به کد نویسی داریم. این پیام تنها شامل مقادیر کلیدی و دوتایی اختصاصی (custom key-value pairs) است.
اضافه کردن FCM به پروژه های اندرویدی (Android Project)
مثل همیشه اولین قدم ایجاد یک Android Studio Project جدید است.
ایجاد یک Android Studio Project جدید
- من با استفاده از یک Empty Activity یک پروژه ی خام را ایجاد کرده ام. اسم آن را FirebasePushExample گذاشته ام.
- شما هم همین کار را انجام دهید و نام دلخواهتان را بر روی پروژه بگذارید.
آموزشLogin کردن به Android Studio با استفاده از اکانت گوگل
اگر در حال حاضر با استفاده از اکانت گوگل وارد Android Studio خود شده اید، می توانید از این بخش بگذرید.
-
در بالا سمت راست IDE مربوط به Android Studio تان تصویر کاربر را مشاهده می کنید. بر روی آن کلیک کنید.
- بر روی دکمه ی Sign In کلیک کنید و با استفاده از نام کاربری و رمز عبور وارد اکانت گوگل خود شوید.
درسته، وجود اکانت گوگل الزامی است. و اگر شما برنامه نویس اندروید باشید، بدیهی است که باید از قبل اکانت گوگل داشته باشید.
آموزش اضافه کردن FCM در Android
بعد از اینکه با استفاده از اکانت گوگل خود وارد Android Studio شدید، می توانید به سرعت FCM را به پروژه ی خود اضافه کنید.
-
• بر روی tools کلیک کرده و Firebase را انتخاب کنید.
بعد از اینکار پنجره ی Assistant در سمت راست باز می شود. در این پنجره بر روی Cloud Messaging کلیک کنید (همانطور که در شکل زیر می بینید).
-
• در اینجا شما باید دو کار را انجام دهید.
به Firebase متصل شوید
-
بعد از انجام این کار پنجره ی جدیدی باز می شود.
- از این پنجره می توانید پروژه ی Firebase جدیدی ایجاد کنید یا در صورت وجود پروژه های Firebase قبلی خود را انتخاب کنید. در اینجا ما قصد داریم پروژه ی Firebase جدید بسازیم. هر اسمی را که می خواهید برای پروژه ی خود انتخاب کنید و بر روی Connect to Firebase کلیک کنید.
-
حالا تا زمانی که پیام سبز رنگ Connected را ببینید منتظر بمانید.
اضافه کردن FCM به برنامه تان
-
حالا بر روی دکمه ی دوم کلیک کنید و FCM را به برنامه ی خود اضافه کنید. باز هم بعد از انجام این کار پنجره ی جدیدی باز می شود و در این پنجره باید تغییرات اعمال شده را تایید کنید.
- بعد از اینکه بر روی این دکمه کلیک کردید تمام کارهایی که برای اضافه کردن FCM به برنامه ی شما نیاز است به صورت خودکار انجام می شود.
راه های دریافت Push Notification
حالا اولین چیزی که نیاز داریم این است که بفهمیم چگونه می توان با استفاده از FCM، notification ها را دریافت یا ارسال کرد. دو راه برای انجام این کار وجود دارد:
- استفاده از FCM Token : زمانی که بخواهیم notification ای را به دستگاه خاصی یا به گروه پویایی از دستگاه ها ارسال کنیم از این روش استفاده میکنیم. بعد از راه اندازی اولیه firebase SDK یک registration token را برای برنامه تولید می کند. از این token برای شناسایی دستگاه استفاده می شود.
- استفاده از Topic : در این روش ما Topic هایی را ایجاد می کنیم و به کاربرانمان اجازه می دهیم که در این Topic ها subscribe کنند. بعد از این کار ما پیام را به Topic ارسال میکنیم و این پیام به تمام کاربران مربوط به این Topic خاص ارسال می شود. در این روش نیازی به ذخیره سازی هیچ tokenی نیست.
در انتخاب هریک از دو روش بالا برای به کارگیری آن ها در برنامه ی خود آزاد هستیم. حتی می توانیم هر دو روش را انتخاب کنیم. اول به یادگیری روش FCM Token می پردازیم و سپس به سراغ روش Topic می رویم.
پیام دهی Firebase Cloud با استفاده از FCM Access Token
در این روش ابتدا access token را ایجاد می کنیم. حالا برای دریافت access token کلاسی را ایجاد می کنیم که FirebaseInstanceIdService گسترش می دهد. این کلاس سرویسی است که ما برای تعریف کردن داخل Manifest file مان به آن نیاز داریم. ببینیم چطور میتوانیم این کار را در پروژه مان انجام دهیم.
تولید Access Token
-
کلاسی با نام MyFirebaseInstanceIdService در پروژه خود ایجاد کنید و کد زیر را بنویسید.
package net.simplifiedcoding.firebasepushexample; import android.util.Log; import com.google.firebase.iid.FirebaseInstanceId; import com.google.firebase.iid.FirebaseInstanceIdService; /** * Created by Belal on 12/8/2017. */ //the class extending FirebaseInstanceIdService public class MyFirebaseInstanceIdService extends FirebaseInstanceIdService { //this method will be called //when the token is generated @Override public void onTokenRefresh() { super.onTokenRefresh(); //now we will have the token String token = FirebaseInstanceId.getInstance().getToken(); //for now we are displaying the token in the log //copy it as this method is called only when the new token is generated //and usually new token is only generated when the app is reinstalled or the data is cleared Log.d("MyRefreshedToken", token); } } - با توجه به اینکه این کلاس یک سرویس است، باید آن را در AndroidManifest.xml هم تعریف کنیم.
-
بنابراین فایل AndroidManifest.xml خود را باز کنید و درست قبل از تگ < /application > کد زیر را اضافه کنید.
< service android:name=".MyFirebaseInstanceIdService" > < intent-filter > < action android:name="com.google.firebase.INSTANCE_ID_EVENT"/ > < /intent-filter > < /service > -
حالا برنامه را اجرا کنید تا token را در logcat خود مشاهده کنید.
- حالا این token را کپی کرده و هرجایی که می خواهید آن را در سیستم خود ذخیره کنید. از این token برای دریافت notification استفاده می کنیم.
مشکلات رایج در Android
اگر نتوانستید token را دریافت کنید موارد زیر را در نظر بگیرید.
- token هر بار تولید نمی شود. token را فقط وقتی دریافت می کنیم که firebase آن را Refresh کند. بنابراین ممکن است اشتباها بعد از اجرای برنامه log را پاک کنید. در این صورت اگر دوباره برنامه را اجرا کنید خبری از token نخواهد بود. برای حل این مشکل باید برنامه را uninstall کنید و بعد از نصب مجدد آن را دوباره اجرا کنید.
- ورژن Google Play Service باید بالاتر از ورژن Firebase ای باشد که شما در پروژه ی خود استفاده می کنید. بنابراین بهتر است همیشه Google Play Service را به آخرین ورژن آپدیت کنید.
- شما در حال مشاهده ی log ای هستید که مربوط به یک دستگاه یا emulator دیگری است. در این صورت مطمئن شوید که emulator انتخاب شده در بالای logcat با emulator جایی که شما دارید برنامه را اجرا می کنید یکی است.
دریافت پیام
برای دریافت پیام باید کلاسی را ایجاد کنیم که باعث گسترش FirebaseMessagingService شود. در اینجا ما متد onMessageReceived() را تعریف می کنیم. این متد زمانی که ما پیامی را دریافت می کنیم فراخوانی می شود. مانند قبل با توجه به اینکه این متد یک سرویس است، باید آن را در AndoirdManifest.xml خود تعریف کنیم.
-
کلاسی با نام MyFirebaseMessagingService ایجاد کنید و کد زیر را بنویسید.
package net.simplifiedcoding.firebasepushexample; import com.google.firebase.messaging.FirebaseMessagingService; import com.google.firebase.messaging.RemoteMessage; /** * Created by Belal on 12/8/2017. */ //class extending FirebaseMessagingService public class MyFirebaseMessagingService extends FirebaseMessagingService { @Override public void onMessageReceived(RemoteMessage remoteMessage) { super.onMessageReceived(remoteMessage); //if the message contains data payload //It is a map of custom keyvalues //we can read it easily if(remoteMessage.getData().size() > 0){ //handle the data message here } //getting the title and the body String title = remoteMessage.getNotification().getTitle(); String body = remoteMessage.getNotification().getBody(); //then here we can use the title and body to build a notification } } -
حالا دوباره آن را درست قبل از تگ < /application > با استفاده از کد XML در AndroidManifest.xml خود تعریف کنید.
< service android:name=".MyFirebaseMessagingService" > < intent-filter > < action android:name="com.google.firebase.MESSAGING_EVENT"/ > < /intent-filter > < /service > - اما برای اینکه بتوانیم notification را ببینیم باید آن را بسازیم. پس بیایید notification را بسازیم.
ساخت Push Notification
برای انجام این کار از یک کلاس تک شیء (Singleton class) استفاده می کنیم.
در اندروید ورژن 8 باید یک notification channel بسازید. در غیر این صورت notification نمایش داده نمی شود.
-
ابتدا در یک کلاس مجزا ثابت هایی را برای Notification Channel مان تعریف میکنیم. کلاسی با نام Constants ایجاد کنید. و کد زیر را بنویسید.
package net.simplifiedcoding.firebasepushexample; /** * Created by Belal on 12/8/2017. */ public class Constants { public static final String CHANNEL_ID = "my_channel_01"; public static final String CHANNEL_NAME = "Simplified Coding Notification"; public static final String CHANNEL_DESCRIPTION = "www.simplifiedcoding.net"; } -
حالا کلاسی با نام MyNotificationManager ایجاد کنید و کد زیر را بنویسید.
package net.simplifiedcoding.firebasepushexample; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.support.v4.app.NotificationCompat; import static android.content.Context.NOTIFICATION_SERVICE; /** * Created by Belal on 12/8/2017. */ public class MyNotificationManager { private Context mCtx; private static MyNotificationManager mInstance; private MyNotificationManager(Context context) { mCtx = context; } public static synchronized MyNotificationManager getInstance(Context context) { if (mInstance == null) { mInstance = new MyNotificationManager(context); } return mInstance; } public void displayNotification(String title, String body) { NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mCtx, Constants.CHANNEL_ID) .setSmallIcon(R.drawable.app_icon) .setContentTitle(title) .setContentText(body); /* * Clicking on the notification will take us to this intent * Right now we are using the MainActivity as this is the only activity we have in our application * But for your project you can customize it as you want * */ Intent resultIntent = new Intent(mCtx, MainActivity.class); /* * Now we will create a pending intent * The method getActivity is taking 4 parameters * All paramters are describing themselves * 0 is the request code (the second parameter) * We can detect this code in the activity that will open by this we can get * Which notification opened the activity * */ PendingIntent pendingIntent = PendingIntent.getActivity(mCtx, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT); /* * Setting the pending intent to notification builder * */ mBuilder.setContentIntent(pendingIntent); NotificationManager mNotifyMgr = (NotificationManager) mCtx.getSystemService(NOTIFICATION_SERVICE); /* * The first parameter is the notification id * better don't give a literal here (right now we are giving a int literal) * because using this id we can modify it later * */ if (mNotifyMgr != null) { mNotifyMgr.notify(1, mBuilder.build()); } } }
آزمایش کردن یک Local Notification
قبل از اینکه جلوتر برویم، باید از عملکرد صحیح notification مطمئن شویم. برای انجام این کار از خود برنامه یک local notification را ایجاد می کنیم.
-
به MainActivity.java بروید و کد زیر را بنویسید.
package net.simplifiedcoding.firebasepushexample; import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Context; import android.graphics.Color; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import com.google.firebase.iid.FirebaseInstanceId; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); /* * If the device is having android oreo we will create a notification channel * */ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); int importance = NotificationManager.IMPORTANCE_HIGH; NotificationChannel mChannel = new NotificationChannel(Constants.CHANNEL_ID, Constants.CHANNEL_NAME, importance); mChannel.setDescription(Constants.CHANNEL_DESCRIPTION); mChannel.enableLights(true); mChannel.setLightColor(Color.RED); mChannel.enableVibration(true); mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400}); mNotificationManager.createNotificationChannel(mChannel); } /* * Displaying a notification locally */ MyNotificationManager.getInstance(this).displayNotification("Greetings", "Hello how are you?"); } } -
حالا برنامه ی خود را اجرا کنید.
- اگر تصویر بالا را مشاهده می کنید که خوب است چون راه را درست رفته اید.
آزمایش کردن Notification از کنسولFirebase
- حالا بیایید از کنسول Firebase یک notification واقعی ارسال کنیم.
-
کنسول firebase را باز کنید، سپس پروژه ی مورد استفاده تان را باز کنید. بعد از انجام این کار از منوی سمت چپ بر روی grow و بعد بر روی notifications کلیک کنید.
-
بعد از اینکه بر روی دکمه ی Send Message کلیک کردید، می بایست پیام خود را در برنامه مشاهده کنید.
- همانطور که میبینید با توجه به اینکه notification را میتوانیم ببینیم، کارمان را درست انجام داده ایم.
پیام دهی Firebase Cloud با استفاده از Topic Subscription
حالا ببینیم چگونه می توانیم notification ها را به دستگاه هایی ارسال کنیم که در گروه مشخصی subscribe شده اند. طبیعتا برای انجام این کار ابتدا باید به صورت زیر گروهی را ایجاد کنیم.
- FirebaseMessaging.getInstance().subscribeToTopic(“put_your_topic_here”); فراخوانی کنید.
- متد بالا کاربر را در topic ، subscribe می کند. و اگر این topic موجود نباشد، firebase ، topic مشخص شده را ایجاد می کند.
- حالا در برنامه ی شما topic هایی را به کاربر میدهیم که کاربر آن ها را subscribe کند. برای انجام این کار interface را ایجاد کنید.
آموزش ایجاد Interface در Android
-
به فایل strings.xml بروید و آرایه ی زیر را تعریف کنید. اجزای این آرایه topicهایی هستند که کاربر می تواند آن ها را subscribe کند.
< resources > < string name="app_name" >FirebasePushExample< /string > < array name="topics" > < item >notifications< /item > < item >promotional_messages< /item > < /array > < /resources > -
حالا کد زیر را در activity_main.xml کپی کنید.
< ?xml version="1.0" encoding="utf-8"? > < RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="net.simplifiedcoding.firebasepushexample.MainActivity" > < LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:orientation="vertical" android:padding="20dp" > < Spinner android:id="@+id/spinnerTopics" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="15dp" android:entries="@array/topics" / > < Button android:id="@+id/buttonSubscribe" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Subscribe" / > < /LinearLayout > < /RelativeLayout > -
کد بالا رابط کاربری زیر را ایجاد می کند.
- کاربر از طریق این رابط کاربری topic مورد نظر را انتخاب کرده و برای subscribe کردن بر روی دکمه ی subscribe کلیک می کند.
آموزشSubscribing کردن در یک topic در Android
-
حالا فایل MainActivity.java را مانند زیر اصلاح کنید. این کد ساده و گویا است و نیازی به توضیح ندارد.
package net.simplifiedcoding.firebasepushexample; import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Context; import android.graphics.Color; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Spinner; import android.widget.Toast; import com.google.firebase.iid.FirebaseInstanceId; import com.google.firebase.messaging.FirebaseMessaging; public class MainActivity extends AppCompatActivity { Spinner spinner; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); spinner = findViewById(R.id.spinnerTopics); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); int importance = NotificationManager.IMPORTANCE_HIGH; NotificationChannel mChannel = new NotificationChannel(Constants.CHANNEL_ID, Constants.CHANNEL_NAME, importance); mChannel.setDescription(Constants.CHANNEL_DESCRIPTION); mChannel.enableLights(true); mChannel.setLightColor(Color.RED); mChannel.enableVibration(true); mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400}); mNotificationManager.createNotificationChannel(mChannel); } findViewById(R.id.buttonSubscribe).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String topic = spinner.getSelectedItem().toString(); FirebaseMessaging.getInstance().subscribeToTopic(topic); Toast.makeText(getApplicationContext(), "Topic Subscribed", Toast.LENGTH_LONG).show(); } }); } } -
حالا دوباره برنامه ی خود را اجرا کنید.
- خب همانطور که مشاهده می کنید، این کد به خوبی کار می کند. حالا بیایید notification ای را به این topic ارسال کنیم.
آموزش ارسال Notification به topic از کنسول Firebase
- دوباره به کنسول firebase و بعد از آن به notification بروید.
-
این بار به جای تنها یک دستگاه notification را به topic ارسال می کنیم.
-
بعد از اینکه بر روی send کلیک می کنید، باید notification زیر را در دستگاه خود مشاهده کنید.
- جالبه! به خوبی جواب میدهد.
آموزش Unsubscribe شدن از یک topic
گاهی اقات ممکن است کاربر دیگر نخواهد notification ای دریافت کند. در این حالت شما باید گزینه ای برای Unsubscribe کردن نیز در نظر بگیرید.
- برای اینکه شما دیگر subscriber یک topic نباشید، باید FirebaseMessaging.getInstance().unsubscribeFromTopic(“your_topic”); را فراخوانی کنید.
آموزش سورس کد آموزش FCM
اگر هنوز در درک این پست مشکل دارید (پست طولانی شد. به همین دلیل باید با دقت آن را دنبال کنید)، می توانید سورس کد من را از سایت GitHub دریافت کنید. برای این کار تنها کافیست با استفاده از کلید یوتیوب زیر این لینک را باز کنید.
برای مطالعه سرفصل آموزش جامع و عملی برنامه نویسی Android کلیک نمایید .