FCM token update and waiting

This commit is contained in:
Yegor Vialov 2020-05-25 14:09:45 +00:00
parent 9a5e35b024
commit 80b5763530
4 changed files with 156 additions and 90 deletions

View File

@ -33,10 +33,9 @@ public class MainActivity extends FlutterActivity {
public void onComplete(@NonNull Task<InstanceIdResult> task) {
if (task.isSuccessful()) {
Context context = getActivity();
SharedPreferences.Editor editor = context.getSharedPreferences("FlutterSharedPreferences", Context.MODE_PRIVATE).edit();
String token = task.getResult().getToken();
editor.putString("flutter.push-token", token);
editor.commit();
UpdateTokenTask updateTokenTask = new UpdateTokenTask(context);
updateTokenTask.execute(token);
}
}
});

View File

@ -40,7 +40,8 @@ public class MessagingService extends FirebaseMessagingService {
@Override
public void onNewToken(String token) {
//TODO update token
UpdateTokenTask updateTokenTask = new UpdateTokenTask(this);
updateTokenTask.execute(token);
}
private void sendNotification(Map<String, String> data) {

View File

@ -0,0 +1,46 @@
package com.keyboardcrumbs.hassclient;
import android.util.Log;
import android.os.AsyncTask;
import java.net.URL;
import java.net.HttpURLConnection;
import java.io.OutputStream;
import android.webkit.URLUtil;
import org.json.JSONObject;
import android.content.SharedPreferences;
import android.content.Context;
import java.lang.ref.WeakReference;
public class UpdateTokenTask extends AsyncTask<String, String, String> {
private static final String TAG = "UpdateTokenTask";
private WeakReference<Context> contextRef;
public UpdateTokenTask(Context context){
contextRef = new WeakReference<>(context);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
Log.d(TAG, "Updating push token");
Context context = contextRef.get();
if (context != null) {
String token = params[0];
SharedPreferences prefs = context.getSharedPreferences("FlutterSharedPreferences", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("flutter.notification-token", token);
editor.commit();
}
return null;
}
}

View File

@ -21,97 +21,117 @@ class MobileAppIntegrationManager {
return '${HomeAssistant().userName}\'s ${DeviceInfoManager().model}';
}
static Future checkAppRegistration() {
static Future checkAppRegistration() async {
int attempts = 1;
bool done = false;
Logger.d("[MobileAppIntegrationManager] Stratring mobile app integration check...");
while (attempts <= 5 && !done) {
Logger.d("[MobileAppIntegrationManager] check attempt $attempts");
String fcmToken = await AppSettings().loadSingle('notification-token');
if (fcmToken != null) {
Logger.d("[MobileAppIntegrationManager] token exist");
await _doCheck(fcmToken);
done = true;
} else {
Logger.d("[MobileAppIntegrationManager] no fcm token. Retry in 5 seconds");
attempts++;
await Future.delayed(Duration(seconds: 5));
}
}
if (!done) {
Logger.e("[MobileAppIntegrationManager] No FCM token");
}
}
static Future _doCheck(String fcmToken) {
Completer completer = Completer();
_appRegistrationData["device_name"] = AppSettings().mobileAppDeviceName ?? getDefaultDeviceName();
AppSettings().loadSingle('push-token').then((fcmToken) {
(_appRegistrationData["app_data"] as Map)["push_token"] = "$fcmToken";
if (AppSettings().webhookId == null) {
Logger.d("Mobile app was not registered yet. Registering...");
var registrationData = Map.from(_appRegistrationData);
(_appRegistrationData["app_data"] as Map)["push_token"] = "$fcmToken";
if (AppSettings().webhookId == null) {
Logger.d("Mobile app was not registered yet. Registering...");
var registrationData = Map.from(_appRegistrationData);
registrationData.addAll({
"app_id": "ha_client",
"app_name": "$appName",
"os_name": DeviceInfoManager().osName,
"supports_encryption": false,
});
if (AppSettings().haVersion >= 104) {
registrationData.addAll({
"app_id": "ha_client",
"app_name": "$appName",
"os_name": DeviceInfoManager().osName,
"supports_encryption": false,
});
if (AppSettings().haVersion >= 104) {
registrationData.addAll({
"device_id": "${DeviceInfoManager().unicDeviceId}"
});
}
ConnectionManager().sendHTTPPost(
endPoint: "/api/mobile_app/registrations",
includeAuthHeader: true,
data: json.encode(registrationData)
).then((response) {
Logger.d("Processing registration responce...");
var responseObject = json.decode(response);
AppSettings().webhookId = responseObject["webhook_id"];
AppSettings().save({
'app-webhook-id': responseObject["webhook_id"]
}).then((prefs) {
completer.complete();
eventBus.fire(ShowPopupEvent(
popup: Popup(
title: "Mobile app Integration was created",
body: "HA Client was registered as MobileApp in your Home Assistant. To start using notifications you need to restart your Home Assistant",
positiveText: "Restart now",
negativeText: "Later",
onPositive: () {
ConnectionManager().callService(domain: "homeassistant", service: "restart");
},
)
));
});
}).catchError((e) {
completer.complete();
if (e is http.Response) {
Logger.e("Error registering the app: ${e.statusCode}: ${e.body}");
} else {
Logger.e("Error registering the app: ${e?.toString()}");
}
_showError();
});
} else {
Logger.d("App was previously registered. Checking...");
var updateData = {
"type": "update_registration",
"data": _appRegistrationData
};
ConnectionManager().sendHTTPPost(
endPoint: "/api/webhook/${AppSettings().webhookId}",
includeAuthHeader: false,
data: json.encode(updateData)
).then((response) {
var registrationData;
try {
registrationData = json.decode(response);
} catch (e) {
registrationData = null;
}
if (registrationData == null || registrationData.isEmpty) {
Logger.w("No registration data in response. MobileApp integration was removed or broken");
_askToRegisterApp();
} else {
Logger.d('App registration works fine');
}
completer.complete();
}).catchError((e) {
if (e is http.Response && e.statusCode == 410) {
Logger.w("MobileApp integration was removed");
_askToRegisterApp();
} else if (e is http.Response) {
Logger.w("Error updating app registration: ${e.statusCode}: ${e.body}");
_showError();
} else {
Logger.w("Error updating app registration: ${e?.toString()}");
_showError();
}
completer.complete();
"device_id": "${DeviceInfoManager().unicDeviceId}"
});
}
});
ConnectionManager().sendHTTPPost(
endPoint: "/api/mobile_app/registrations",
includeAuthHeader: true,
data: json.encode(registrationData)
).then((response) {
Logger.d("Processing registration responce...");
var responseObject = json.decode(response);
AppSettings().webhookId = responseObject["webhook_id"];
AppSettings().save({
'app-webhook-id': responseObject["webhook_id"]
}).then((prefs) {
completer.complete();
eventBus.fire(ShowPopupEvent(
popup: Popup(
title: "Mobile app Integration was created",
body: "HA Client was registered as MobileApp in your Home Assistant. To start using notifications you need to restart your Home Assistant",
positiveText: "Restart now",
negativeText: "Later",
onPositive: () {
ConnectionManager().callService(domain: "homeassistant", service: "restart");
},
)
));
});
}).catchError((e) {
completer.complete();
if (e is http.Response) {
Logger.e("Error registering the app: ${e.statusCode}: ${e.body}");
} else {
Logger.e("Error registering the app: ${e?.toString()}");
}
_showError();
});
} else {
Logger.d("App was previously registered. Checking...");
var updateData = {
"type": "update_registration",
"data": _appRegistrationData
};
ConnectionManager().sendHTTPPost(
endPoint: "/api/webhook/${AppSettings().webhookId}",
includeAuthHeader: false,
data: json.encode(updateData)
).then((response) {
var registrationData;
try {
registrationData = json.decode(response);
} catch (e) {
registrationData = null;
}
if (registrationData == null || registrationData.isEmpty) {
Logger.w("No registration data in response. MobileApp integration was removed or broken");
_askToRegisterApp();
} else {
Logger.d('App registration works fine');
}
completer.complete();
}).catchError((e) {
if (e is http.Response && e.statusCode == 410) {
Logger.w("MobileApp integration was removed");
_askToRegisterApp();
} else if (e is http.Response) {
Logger.w("Error updating app registration: ${e.statusCode}: ${e.body}");
_showError();
} else {
Logger.w("Error updating app registration: ${e?.toString()}");
_showError();
}
completer.complete();
});
}
return completer.future;
}