diff --git a/NcmbFcmPlugin/build.gradle b/NcmbFcmPlugin/build.gradle index 3f4d4321..c735532c 100644 --- a/NcmbFcmPlugin/build.gradle +++ b/NcmbFcmPlugin/build.gradle @@ -15,7 +15,6 @@ buildscript { allprojects { repositories { - jcenter() google() } } diff --git a/NcmbFcmPlugin/ncmbfcmplugin/release/ncmbfcmplugin.aar b/NcmbFcmPlugin/ncmbfcmplugin/release/ncmbfcmplugin.aar index 4829053a..862f66a8 100644 Binary files a/NcmbFcmPlugin/ncmbfcmplugin/release/ncmbfcmplugin.aar and b/NcmbFcmPlugin/ncmbfcmplugin/release/ncmbfcmplugin.aar differ diff --git a/NcmbFcmPlugin/ncmbfcmplugin/src/main/java/com/nifcloud/mbaas/ncmbfcmplugin/FCMInit.java b/NcmbFcmPlugin/ncmbfcmplugin/src/main/java/com/nifcloud/mbaas/ncmbfcmplugin/FCMInit.java index 0c185877..79a28afb 100644 --- a/NcmbFcmPlugin/ncmbfcmplugin/src/main/java/com/nifcloud/mbaas/ncmbfcmplugin/FCMInit.java +++ b/NcmbFcmPlugin/ncmbfcmplugin/src/main/java/com/nifcloud/mbaas/ncmbfcmplugin/FCMInit.java @@ -27,6 +27,7 @@ import com.google.android.gms.common.GoogleApiAvailability; import com.google.android.gms.tasks.OnCanceledListener; import com.google.android.gms.tasks.OnCompleteListener; +import com.google.android.gms.tasks.OnFailureListener; import com.google.android.gms.tasks.Task; import com.google.firebase.FirebaseApp; import com.google.firebase.iid.FirebaseInstanceId; @@ -40,6 +41,10 @@ //FCMの初期化処理を扱います public class FCMInit extends Activity { + private static final String NOT_SUPPORT_PLAY_SERVICE_MESSAGE = + "This device is not supported google-play-services-APK."; + private static final String CAN_NOT_GET_TOKEN_MESSAGE = + "Can not get device token"; public static void Init(){ @@ -47,46 +52,50 @@ public static void Init(){ // Init firebase app FirebaseApp.initializeApp(UnityPlayer.currentActivity.getApplicationContext()); if (!FirebaseApp.getApps(UnityPlayer.currentActivity.getApplicationContext()).isEmpty()) { - // Add listener for token + + //On Complete Listener FirebaseInstanceId.getInstance().getInstanceId().addOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { - if(task.isSuccessful()) { - final String token = task.getResult().getToken(); - //Setting chanel for Android O - if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ - NCMBNotificationUtils utils = new NCMBNotificationUtils(UnityPlayer.currentActivity); - utils.settingDefaultChannels(); - } - UnityPlayer.currentActivity.runOnUiThread(new Runnable() { - public void run() { - UnityPlayer.UnitySendMessage("NCMBManager", "onTokenReceived", token); + if(task.isSuccessful()) { + final String token = task.getResult().getToken(); + //Setting chanel for Android O + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ + NCMBNotificationUtils utils = new NCMBNotificationUtils(UnityPlayer.currentActivity); + utils.settingDefaultChannels(); } - }); - } else{ - UnityPlayer.currentActivity.runOnUiThread(new Runnable() { - public void run() { - UnityPlayer.UnitySendMessage("NCMBManager", "OnRegistration", "Can not get token"); - } - }); - } + //Save recent token + NCMBNotificationUtils.saveRecentToken(token); + //Send token to NCMBManager + sendMessageToManager("onTokenReceived", token); + } else{ + sendMessageToManager("OnRegistration", CAN_NOT_GET_TOKEN_MESSAGE); + } } }); + //On Canceled Listener FirebaseInstanceId.getInstance().getInstanceId().addOnCanceledListener(new OnCanceledListener() { @Override public void onCanceled() { - UnityPlayer.currentActivity.runOnUiThread(new Runnable() { - public void run() { - UnityPlayer.UnitySendMessage("NCMBManager", "OnRegistration", "Can not get token"); - } - }); + sendMessageToManager("OnRegistration", CAN_NOT_GET_TOKEN_MESSAGE); } }); + + //On Failure Listener + FirebaseInstanceId.getInstance().getInstanceId().addOnFailureListener(new OnFailureListener() { + @Override + public void onFailure(@NonNull Exception e) { + Log.e("Error", e.toString()); + sendMessageToManager("OnRegistration", CAN_NOT_GET_TOKEN_MESSAGE); + } + }); + } else { + sendMessageToManager("OnRegistration", CAN_NOT_GET_TOKEN_MESSAGE); } } else { - UnityPlayer.UnitySendMessage("NCMBManager", "OnRegistration", "This device is not supported google-play-services-APK."); + sendMessageToManager("OnRegistration", NOT_SUPPORT_PLAY_SERVICE_MESSAGE); } } @@ -135,4 +144,15 @@ public static String getInstallationProperty(){ return json.toString(); } + + /** + * Send message to NCMBManager + */ + protected static void sendMessageToManager(final String method, final String message){ + UnityPlayer.currentActivity.runOnUiThread(new Runnable() { + public void run() { + UnityPlayer.UnitySendMessage("NCMBManager", method, message); + } + }); + } } diff --git a/NcmbFcmPlugin/ncmbfcmplugin/src/main/java/com/nifcloud/mbaas/ncmbfcmplugin/NCMBFirebaseMessagingService.java b/NcmbFcmPlugin/ncmbfcmplugin/src/main/java/com/nifcloud/mbaas/ncmbfcmplugin/NCMBFirebaseMessagingService.java index 5775828d..0d83652a 100755 --- a/NcmbFcmPlugin/ncmbfcmplugin/src/main/java/com/nifcloud/mbaas/ncmbfcmplugin/NCMBFirebaseMessagingService.java +++ b/NcmbFcmPlugin/ncmbfcmplugin/src/main/java/com/nifcloud/mbaas/ncmbfcmplugin/NCMBFirebaseMessagingService.java @@ -52,13 +52,17 @@ public class NCMBFirebaseMessagingService extends FirebaseMessagingService { */ @Override public void onNewToken(String token) { - // Send refesh token to update installation + final String saveToken = token; - UnityPlayer.currentActivity.runOnUiThread(new Runnable() { - public void run() { - UnityPlayer.UnitySendMessage("NCMBManager", "onTokenReceived", saveToken); - } - }); + String recentToken = NCMBNotificationUtils.getRecentToken(); + + // Send refesh token to update installation + if ( !recentToken.isEmpty() && token.compareTo(recentToken) != 0 ) { + // Save recent token + NCMBNotificationUtils.saveRecentToken(token); + // Send token to NCMBManager + FCMInit.sendMessageToManager("onTokenReceived", saveToken); + } } @Override diff --git a/NcmbFcmPlugin/ncmbfcmplugin/src/main/java/com/nifcloud/mbaas/ncmbfcmplugin/NCMBNotificationUtils.java b/NcmbFcmPlugin/ncmbfcmplugin/src/main/java/com/nifcloud/mbaas/ncmbfcmplugin/NCMBNotificationUtils.java index eda0c48e..036e17d4 100644 --- a/NcmbFcmPlugin/ncmbfcmplugin/src/main/java/com/nifcloud/mbaas/ncmbfcmplugin/NCMBNotificationUtils.java +++ b/NcmbFcmPlugin/ncmbfcmplugin/src/main/java/com/nifcloud/mbaas/ncmbfcmplugin/NCMBNotificationUtils.java @@ -21,9 +21,12 @@ import android.app.NotificationManager; import android.content.Context; import android.content.ContextWrapper; +import android.content.SharedPreferences; import android.graphics.Color; import android.os.Build; +import com.unity3d.player.UnityPlayer; + /** * The NCMBNotificationUtils Class contains register channel and get channel method */ @@ -65,4 +68,17 @@ public NotificationManager getManager() { public static String getDefaultChannel(){ return DEFAULT_CHANNEL_ID; } + + protected static void saveRecentToken(String token){ + SharedPreferences.Editor editor = UnityPlayer.currentActivity + .getSharedPreferences("ncmbToken", Context.MODE_PRIVATE).edit(); + editor.putString("recentToken", token); + editor.commit(); + } + + protected static String getRecentToken(){ + SharedPreferences recentTokenPref = UnityPlayer.currentActivity + .getSharedPreferences("ncmbToken", Context.MODE_PRIVATE); + return recentTokenPref.getString("recentToken", ""); + } } diff --git a/ncmb_unity/Assets/NCMB/NCMBManager.cs b/ncmb_unity/Assets/NCMB/NCMBManager.cs index 8b00bd3c..92daf497 100644 --- a/ncmb_unity/Assets/NCMB/NCMBManager.cs +++ b/ncmb_unity/Assets/NCMB/NCMBManager.cs @@ -97,6 +97,13 @@ void OnRegistration (string message) { Inited = true; + //Exceute NCMBDeviceTokenCallbackQueue + if(message != null && String.Compare(message,"") != 0 ){ + NCMBDeviceTokenCallbackQueue.GetInstance().execQueue(null, + new NCMBException (new Exception (message))); + } else { + NCMBDeviceTokenCallbackQueue.GetInstance().execQueue(_token, null); + } if (onRegistration != null) { if (message == "") { message = null; @@ -250,26 +257,26 @@ internal void onTokenReceived (string token) installation.SaveAsync ((NCMBException saveError) => { //更新実行 if (saveError != null) { //対処可能なエラー - if (saveError.ErrorCode.Equals(NCMBException.DUPPLICATION_ERROR)){ - //過去に登録したデバイストークンと衝突。アプリの再インストール後などに発生 - updateExistedInstallation (installation, path); - } else if (saveError.ErrorCode.Equals(NCMBException.DATA_NOT_FOUND)) { - //保存失敗 : 端末情報の該当データがない - installation.ObjectId = null; - installation.SaveAsync((NCMBException updateError) => { - if (updateError != null){ - OnRegistration(updateError.ErrorMessage); - } else { - OnRegistration(""); - } - }); - } else { - //想定外のエラー - OnRegistration (saveError.ErrorMessage); + if (saveError.ErrorCode.Equals(NCMBException.DUPPLICATION_ERROR)){ + //過去に登録したデバイストークンと衝突。アプリの再インストール後などに発生 + updateExistedInstallation (installation, path); + } else if (saveError.ErrorCode.Equals(NCMBException.DATA_NOT_FOUND)) { + //保存失敗 : 端末情報の該当データがない + installation.ObjectId = null; + installation.SaveAsync((NCMBException updateError) => { + if (updateError != null){ + OnRegistration(updateError.ErrorMessage); + } else { + OnRegistration(""); + } + }); + } else { + //想定外のエラー + OnRegistration (saveError.ErrorMessage); + } + } else { + OnRegistration (""); } - } else { - OnRegistration (""); - } }); } @@ -277,23 +284,21 @@ private void updateExistedInstallation (NCMBInstallation installation, string pa { //デバイストークンを更新 NCMBQuery query = NCMBInstallation.GetQuery (); //ObjectId検索 - installation.GetDeviceToken((token, error) => { - query.WhereEqualTo("deviceToken", token); - query.FindAsync ((List objList, NCMBException findError) => { - if (findError != null) { - OnRegistration (findError.ErrorMessage); - } else if (objList.Count != 0) { - installation.ObjectId = objList [0].ObjectId; - installation.SaveAsync ((NCMBException installationUpdateError) => { - if (installationUpdateError != null) { - OnRegistration (installationUpdateError.ErrorMessage); - } else { - OnRegistration (""); - } - }); - } - }); - }); + query.WhereEqualTo("deviceToken", _token); + query.FindAsync ((List objList, NCMBException findError) => { + if (findError != null) { + OnRegistration (findError.ErrorMessage); + } else if (objList.Count != 0) { + installation.ObjectId = objList [0].ObjectId; + installation.SaveAsync ((NCMBException installationUpdateError) => { + if (installationUpdateError != null) { + OnRegistration (installationUpdateError.ErrorMessage); + } else { + OnRegistration (""); + } + }); + } + }); } //ディスク入出力関数 diff --git a/ncmb_unity/Assets/NCMB/Script/NCMBDeviceTokenCallbackQueue.cs b/ncmb_unity/Assets/NCMB/Script/NCMBDeviceTokenCallbackQueue.cs new file mode 100644 index 00000000..01bf0c7b --- /dev/null +++ b/ncmb_unity/Assets/NCMB/Script/NCMBDeviceTokenCallbackQueue.cs @@ -0,0 +1,75 @@ +/******* + Copyright 2017-2018 FUJITSU CLOUD TECHNOLOGIES LIMITED All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + **********/ + +using System; +using NCMB.Internal; +using UnityEngine; +using System.Collections.Generic; + +namespace NCMB +{ + public class NCMBDeviceTokenCallbackQueue + { + private static NCMBDeviceTokenCallbackQueue instance; + + Queue> queue; + public static NCMBDeviceTokenCallbackQueue GetInstance() + { + if (instance == null) + { + instance = new NCMBDeviceTokenCallbackQueue(); + } + return instance; + } + + public Boolean isDuringSaveInstallation() + { + return (queue != null); + } + + void beginSaveInstallation() + { + if (queue == null) + { + queue = new Queue>(); + } + } + public void addQueue(NCMBGetCallback callback) + { + beginSaveInstallation(); + queue.Enqueue(callback); + } + + public void execQueue(String token, NCMBException e) + { + if (queue == null) + { + return; + } + while (queue.Count > 0) + { + NCMBGetCallback callback = queue.Dequeue(); + callback(token, e); + } + + endSaveInstallation(); + } + void endSaveInstallation() + { + queue = null; + } + } +} \ No newline at end of file diff --git a/ncmb_unity/Assets/NCMB/Script/NCMBInstallation.cs b/ncmb_unity/Assets/NCMB/Script/NCMBInstallation.cs index 2c30e607..b7482652 100644 --- a/ncmb_unity/Assets/NCMB/Script/NCMBInstallation.cs +++ b/ncmb_unity/Assets/NCMB/Script/NCMBInstallation.cs @@ -131,25 +131,23 @@ public string DeviceToken { /// /// コールバック public void GetDeviceToken(NCMBGetCallback callback){ - if(this.ContainsKey("deviceToken") && this["deviceToken"] != null ){ + if (NCMBDeviceTokenCallbackQueue.GetInstance().isDuringSaveInstallation()) + { + NCMBDeviceTokenCallbackQueue.GetInstance().addQueue(callback); + return; + } + + if (this.ContainsKey("deviceToken") && this["deviceToken"] != null) + { callback((string)this["deviceToken"], null); - } else { - new Thread(() => { - for (int i = 0; i < 10; i++){ - if (NCMBManager._token != null){ - this["deviceToken"] = NCMBManager._token; - break; - } - Thread.Sleep(500); - } - if (callback != null){ - if (this.ContainsKey("deviceToken") && this["deviceToken"] != null){ - callback((string)this["deviceToken"], null); - } else { - callback(null, new NCMBException("Can not get device token")); - } - } - }).Start(); + return; + } + else + { + NCMBDeviceTokenCallbackQueue.GetInstance().addQueue(callback); + #if UNITY_ANDROID + NCMBPush.Register(); + #endif } } diff --git a/ncmb_unity/Assets/Plugins/Android/ncmbfcmplugin.aar b/ncmb_unity/Assets/Plugins/Android/ncmbfcmplugin.aar index 4829053a..862f66a8 100644 Binary files a/ncmb_unity/Assets/Plugins/Android/ncmbfcmplugin.aar and b/ncmb_unity/Assets/Plugins/Android/ncmbfcmplugin.aar differ