Androidに「Firebase Cloud Messaging」を実装するときにいろいろと参考にしたのですが、
バージョン違いのためか実装に苦労したので今後のためにまとめておきます。
■ANDROID
・build.gradle
1 2 3 4 5 6 7 |
dependencies { implementation 'com.google.firebase:firebase-core:17.0.1' implementation 'com.google.firebase:firebase-auth:18.1.0' implementation 'com.google.firebase:firebase-messaging:19.0.1' } apply plugin: 'com.google.gms.google-services' |
いろいろな記事を参考にしていると「firebase-core」「firebase-messaging」の最新のバージョンの関連がどれかわからなくなったので以下のサイトから最新の関連を見ました。
https://firebase.google.com/support/release-notes/android
・Android.Manifest.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@mipmap/ic_launcher" /> <meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/colorAccent" /> <meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="@string/channel_id"/> <service android:name=".data.source.remote.MyFcmListenerService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> |
channel_idの値は任意で何か設定すればOK
・Main.Activity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
@Override protected void onCreate(Bundle savedInstanceState) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { createChannel(); } try { FirebaseInstanceId.getInstance().getInstanceId() .addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() { @Override public void onComplete(@NonNull Task<InstanceIdResult> task) { if (!task.isSuccessful()) { return; } // Get new Instance ID token String token = task.getResult().getToken(); //ここでtokenをサーバーに保存する } }); }catch (Exception e){ } } //Oreo以降用のプッシュ通知用チャネル作成 private void createChannel(){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); NotificationChannel channel = new NotificationChannel( getString(R.string.channel_id), getString(R.string.channel_name), NotificationManager.IMPORTANCE_DEFAULT ); // 通知時にライトを有効にする channel.enableLights(true); // 通知時のライトの色 channel.setLightColor(Color.WHITE); // ロック画面での表示レベル channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC); // チャンネルの登録 manager.createNotificationChannel(channel); } } |
Build.VERSION_CODES.O以降はプッシュ通知用のチャンネルを作成しておかないと通知が届きません
・MyFcmListenerService.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
public class MyFcmListenerService extends FirebaseMessagingService { @Override public void onNewToken(String token) { sendRegistrationToServer(token); } private void sendRegistrationToServer(String token) { try { //ここでtokenをサーバーに保存する } catch (Exception e) { } } @Override public void onMessageReceived(RemoteMessage remoteMessage) { try{ String msgBody = null; Map data = remoteMessage.getData(); String message = data.get("message").toString(); String infoIdStr = data.get("info_id").toString(); sendNotificationAsInfo(message, Long.parseLong(infoIdStr)); }catch(Exception e){ } } private void sendNotificationAsInfo(String message, long infoId) { LogUtil.i("sendNotificationAsInfo:" + message); Intent mainIntent = new Intent(this, MainActivity.class); Intent intent = new Intent(this, InfoDetailActivity.class); intent.putExtra(InfoDetailActivity.EXTRA_INFO_ID, infoId); mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); sendNotificationInternal(message, PendingIntent.getActivities(this, 0 /* Request code */, new Intent[]{mainIntent, intent}, PendingIntent.FLAG_ONE_SHOT)); } private void sendNotificationInternal(String message, PendingIntent pendingIntent) { Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.tsuuchi) .setContentTitle("お知らせ") .setContentText(message) .setAutoCancel(true) .setSound(defaultSoundUri) .setContentIntent(pendingIntent); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { notificationBuilder.setChannelId(getString(R.string.channel_id)); } NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(0 /* ID of notification */, notificationBuilder.build()); } |
■プッシュ通知を送信するPHP側の処理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
$apikey = "xxxxxxxxxxxxxxxxxxxxxxxxxxx"; $rq = new HTTP_Request("https://fcm.googleapis.com/fcm/send"); $rq->setMethod(HTTP_REQUEST_METHOD_POST); $rq->addHeader("Authorization", "key=".$apikey); $rq->addHeader("Content-Type", "application/json"); $postData = array(); $postData["message"] = $push_msg; $jdata = array( 'to' => $regid, 'data' => $postData ); $rq->addRawPostData(json_encode($jdata)); if (!PEAR::isError($rq->sendRequest())) { $this->log("GCM:SUCCESS"); echo "OK"; } else { $this->log("GCM:ERROR"); print "\nError has occurred"; } |
$apikeyの値はfirebaseのページで登録したプロジェクトの値を使用してください。
$regidはandroidアプリから保存したトークンの値を使用します。
参考記事によってはトークンを入れる先が「to」ではなく「registration_ids」だったりして何度も失敗しましたが、
‘to’ => $regid, ‘data’ => $postDataの値をjsonエンコードすると送信できました。
以上でプッシュ通知が送信できました。