mirror of
https://gitlab.com/famedly/fluffychat.git
synced 2025-04-18 16:07:54 +02:00
feat: Use Firebase Cloud Messaging over UP
This switches to the FOSS implementation of the google libraries so we have no more Blobs there.
This commit is contained in:
parent
4e73e6d9f4
commit
23f9be2fd5
@ -62,7 +62,6 @@ integration_test:
|
||||
# properly set the homeserver IP for the test
|
||||
- sed -i "s/10.0.2.2/$(drill docker | grep -m 1 -P "\d+\.\d+\.\d+.\d+" | awk -F ' ' '{print $NF}')/g" integration_test/users.dart
|
||||
- curl docker:8008/_matrix/static/ 2> /dev/null | grep "It works! Synapse is running"
|
||||
- git apply ./scripts/enable-android-google-services.patch
|
||||
- flutter pub get
|
||||
- flutter test integration_test
|
||||
tags:
|
||||
|
@ -78,8 +78,9 @@ flutter {
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
//implementation 'com.google.firebase:firebase-messaging:19.0.1' // Workaround for https://github.com/microg/android_packages_apps_GmsCore/issues/313#issuecomment-617651698
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'androidx.test:runner:1.1.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
|
||||
implementation 'androidx.multidex:multidex:2.0.1'
|
||||
implementation('com.github.UnifiedPush:android-foss_embedded_fcm_distributor:1.0.0-beta1')
|
||||
}
|
||||
|
||||
//apply plugin: 'com.google.gms.google-services'
|
||||
|
@ -122,7 +122,13 @@
|
||||
<action android:name="org.unifiedpush.flutter.connector.REGISTRATION_FAILED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:enabled="true" android:name=".EmbeddedDistributor" android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="org.unifiedpush.android.distributor.feature.BYTES_MESSAGE"/>
|
||||
<action android:name="org.unifiedpush.android.distributor.REGISTER"/>
|
||||
<action android:name="org.unifiedpush.android.distributor.UNREGISTER"/>
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<meta-data
|
||||
|
@ -0,0 +1,14 @@
|
||||
package chat.fluffy.fluffychat
|
||||
|
||||
import android.content.Context
|
||||
import org.unifiedpush.android.foss_embedded_fcm_distributor.EmbeddedDistributorReceiver
|
||||
|
||||
class EmbeddedDistributor: EmbeddedDistributorReceiver() {
|
||||
|
||||
override val googleProjectNumber = "865731724731" // This value comes from the google-services.json
|
||||
|
||||
override fun getEndpoint(context: Context, token: String, instance: String): String {
|
||||
// This returns the endpoint of your FCM Rewrite-Proxy
|
||||
return "https://push.fluffychat.im/_matrix/push/v1/notify?token=$token"
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
/*package chat.fluffy.fluffychat
|
||||
|
||||
import com.famedly.fcm_shared_isolate.FcmSharedIsolateService
|
||||
|
||||
import chat.fluffy.fluffychat.MainActivity
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
import io.flutter.view.FlutterMain
|
||||
import io.flutter.embedding.engine.dart.DartExecutor.DartEntrypoint
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.WindowManager
|
||||
|
||||
class FcmPushService : FcmSharedIsolateService() {
|
||||
override fun getEngine(): FlutterEngine {
|
||||
return provideEngine(getApplicationContext())
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun provideEngine(context: Context): FlutterEngine {
|
||||
var engine = MainActivity.engine
|
||||
if (engine == null) {
|
||||
engine = MainActivity.provideEngine(context)
|
||||
engine.getLocalizationPlugin().sendLocalesToFlutter(
|
||||
context.getResources().getConfiguration())
|
||||
engine.getDartExecutor().executeDartEntrypoint(
|
||||
DartEntrypoint.createDefault())
|
||||
}
|
||||
return engine
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
@ -8,7 +8,6 @@ buildscript {
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.2.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
//classpath 'com.google.gms:google-services:4.3.8'
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ import 'package:vrouter/vrouter.dart';
|
||||
|
||||
import 'package:fluffychat/utils/matrix_sdk_extensions.dart/client_stories_extension.dart';
|
||||
import 'package:fluffychat/utils/push_helper.dart';
|
||||
import 'package:fluffychat/utils/sentry_controller.dart';
|
||||
import '../config/app_config.dart';
|
||||
import '../config/setting_keys.dart';
|
||||
import 'famedlysdk_store.dart';
|
||||
@ -52,7 +53,6 @@ class BackgroundPush {
|
||||
Client client;
|
||||
BuildContext? context;
|
||||
GlobalKey<VRouterState>? router;
|
||||
String? _fcmToken;
|
||||
void Function(String errorMsg, {Uri? link})? onFcmError;
|
||||
L10n? l10n;
|
||||
Store? _store;
|
||||
@ -65,8 +65,6 @@ class BackgroundPush {
|
||||
|
||||
final pendingTests = <String, Completer<void>>{};
|
||||
|
||||
final dynamic firebase = null; //FcmSharedIsolate();
|
||||
|
||||
DateTime? lastReceivedPush;
|
||||
|
||||
bool upAction = false;
|
||||
@ -77,17 +75,6 @@ class BackgroundPush {
|
||||
onRoomSync ??= client.onSync.stream
|
||||
.where((s) => s.hasRoomUpdate)
|
||||
.listen((s) => _onClearingPush(getFromServer: false));
|
||||
firebase?.setListeners(
|
||||
onMessage: (message) => pushHelper(
|
||||
PushNotification.fromJson(
|
||||
Map<String, dynamic>.from(message['data'] ?? message)),
|
||||
client: client,
|
||||
l10n: l10n,
|
||||
activeRoomId: router?.currentState?.pathParameters['roomid'],
|
||||
onSelectNotification: goToRoom,
|
||||
),
|
||||
onNewToken: _newFcmToken,
|
||||
);
|
||||
if (Platform.isAndroid) {
|
||||
UnifiedPush.initialize(
|
||||
onNewEndpoint: _newUpEndpoint,
|
||||
@ -123,20 +110,12 @@ class BackgroundPush {
|
||||
StreamSubscription<LoginState>? onLogin;
|
||||
StreamSubscription<SyncUpdate>? onRoomSync;
|
||||
|
||||
void _newFcmToken(String token) {
|
||||
_fcmToken = token;
|
||||
setupPush();
|
||||
}
|
||||
|
||||
Future<void> setupPusher({
|
||||
String? gatewayUrl,
|
||||
String? token,
|
||||
Set<String?>? oldTokens,
|
||||
bool useDeviceSpecificAppId = false,
|
||||
}) async {
|
||||
if (PlatformInfos.isIOS) {
|
||||
await firebase?.requestPermission();
|
||||
}
|
||||
final clientName = PlatformInfos.clientName;
|
||||
oldTokens ??= <String>{};
|
||||
final pushers = await (client.getPushers().catchError((e) {
|
||||
@ -229,11 +208,10 @@ class BackgroundPush {
|
||||
if (upAction) {
|
||||
return;
|
||||
}
|
||||
if (!PlatformInfos.isIOS &&
|
||||
(await UnifiedPush.getDistributors()).isNotEmpty) {
|
||||
if ((await UnifiedPush.getDistributors()).isNotEmpty) {
|
||||
await setupUp();
|
||||
} else {
|
||||
await setupFirebase();
|
||||
_noFcmWarning();
|
||||
}
|
||||
|
||||
// ignore: unawaited_futures
|
||||
@ -273,24 +251,6 @@ class BackgroundPush {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> setupFirebase() async {
|
||||
Logs().v('Setup firebase');
|
||||
if (_fcmToken?.isEmpty ?? true) {
|
||||
try {
|
||||
_fcmToken = await firebase?.getToken();
|
||||
if (_fcmToken == null) throw ('PushToken is null');
|
||||
} catch (e, s) {
|
||||
Logs().w('[Push] cannot get token', e, e is String ? null : s);
|
||||
await _noFcmWarning();
|
||||
return;
|
||||
}
|
||||
}
|
||||
await setupPusher(
|
||||
gatewayUrl: AppConfig.pushNotificationsGatewayUrl,
|
||||
token: _fcmToken,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> goToRoom(String? roomId) async {
|
||||
try {
|
||||
Logs().v('[Push] Attempting to go to room $roomId...');
|
||||
@ -321,8 +281,20 @@ class BackgroundPush {
|
||||
await _upUnregistered(i);
|
||||
return;
|
||||
}
|
||||
|
||||
var endpoint =
|
||||
'https://matrix.gateway.unifiedpush.org/_matrix/push/v1/notify';
|
||||
|
||||
if (newEndpoint.startsWith(AppConfig.pushNotificationsGatewayUrl)) {
|
||||
await setupPusher(
|
||||
gatewayUrl: AppConfig.pushNotificationsGatewayUrl,
|
||||
token: Uri.parse(newEndpoint).queryParameters['token'],
|
||||
);
|
||||
await store.setItem(SettingKeys.unifiedPushEndpoint, newEndpoint);
|
||||
await store.setItemBool(SettingKeys.unifiedPushRegistered, true);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
final url = Uri.parse(newEndpoint)
|
||||
.replace(
|
||||
@ -344,16 +316,11 @@ class BackgroundPush {
|
||||
'[Push] No self-hosted unified push gateway present: ' + newEndpoint);
|
||||
}
|
||||
Logs().i('[Push] UnifiedPush using endpoint ' + endpoint);
|
||||
final oldTokens = <String?>{};
|
||||
try {
|
||||
final fcmToken = await firebase?.getToken();
|
||||
oldTokens.add(fcmToken);
|
||||
} catch (_) {}
|
||||
|
||||
await setupPusher(
|
||||
gatewayUrl: endpoint,
|
||||
token: newEndpoint,
|
||||
oldTokens: oldTokens,
|
||||
useDeviceSpecificAppId: true,
|
||||
useDeviceSpecificAppId: false,
|
||||
);
|
||||
await store.setItem(SettingKeys.unifiedPushEndpoint, newEndpoint);
|
||||
await store.setItemBool(SettingKeys.unifiedPushRegistered, true);
|
||||
@ -374,17 +341,24 @@ class BackgroundPush {
|
||||
}
|
||||
|
||||
Future<void> _onUpMessage(Uint8List message, String i) async {
|
||||
upAction = true;
|
||||
final data = Map<String, dynamic>.from(
|
||||
json.decode(utf8.decode(message))['notification']);
|
||||
// UP may strip the devices list
|
||||
data['devices'] ??= [];
|
||||
await pushHelper(
|
||||
PushNotification.fromJson(data),
|
||||
client: client,
|
||||
l10n: l10n,
|
||||
activeRoomId: router?.currentState?.pathParameters['roomid'],
|
||||
);
|
||||
try {
|
||||
Logs().d('Received Push Notification over UP');
|
||||
final jsonMessage = json.decode(utf8.decode(message));
|
||||
upAction = true;
|
||||
final data =
|
||||
Map<String, dynamic>.from(jsonMessage['notification'] ?? jsonMessage);
|
||||
// UP may strip the devices list
|
||||
data['devices'] ??= [];
|
||||
await pushHelper(
|
||||
PushNotification.fromJson(data),
|
||||
client: client,
|
||||
l10n: l10n,
|
||||
activeRoomId: router?.currentState?.pathParameters['roomid'],
|
||||
);
|
||||
} catch (e, s) {
|
||||
Logs().wtf('Push Helper has crashed!', e, s);
|
||||
SentryController.captureException(e, s);
|
||||
}
|
||||
}
|
||||
|
||||
/// Workaround for the problem that local notification IDs must be int but we
|
||||
|
@ -25,7 +25,6 @@ dependencies:
|
||||
email_validator: ^2.0.1
|
||||
emoji_picker_flutter: ^1.1.2
|
||||
encrypt: ^5.0.1
|
||||
#fcm_shared_isolate: ^0.1.0
|
||||
file_picker_cross: ^4.6.0
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
git apply ./scripts/enable-android-google-services.patch
|
||||
FLUFFYCHAT_ORIG_GROUP="im.fluffychat"
|
||||
FLUFFYCHAT_ORIG_TEAM="4NXF6Z997G"
|
||||
#FLUFFYCHAT_NEW_GROUP="com.example.fluffychat"
|
||||
|
@ -2,7 +2,6 @@
|
||||
flutter pub get
|
||||
flutter pub run import_sorter:main --no-comments --exit-if-changed
|
||||
flutter format lib/ test/ --set-exit-if-changed
|
||||
git apply ./scripts/enable-android-google-services.patch
|
||||
flutter pub get
|
||||
flutter analyze
|
||||
flutter pub run dart_code_metrics:metrics lib -r gitlab > code-quality-report.json || true
|
@ -1,168 +0,0 @@
|
||||
diff --git a/android/app/build.gradle b/android/app/build.gradle
|
||||
index 001fbd72..339b35af 100644
|
||||
--- a/android/app/build.gradle
|
||||
+++ b/android/app/build.gradle
|
||||
@@ -44,7 +44,7 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId "chat.fluffy.fluffychat"
|
||||
- minSdkVersion 16
|
||||
+ minSdkVersion 19
|
||||
targetSdkVersion 30
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
@@ -68,6 +68,10 @@ android {
|
||||
}
|
||||
release {
|
||||
signingConfig signingConfigs.release
|
||||
+ minifyEnabled false
|
||||
+ shrinkResources false
|
||||
+
|
||||
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -78,8 +82,11 @@ flutter {
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
- //implementation 'com.google.firebase:firebase-messaging:19.0.1' // Workaround for https://github.com/microg/android_packages_apps_GmsCore/issues/313#issuecomment-617651698
|
||||
+ implementation 'com.google.firebase:firebase-messaging:19.0.1' // Workaround for https://github.com/microg/android_packages_apps_GmsCore/issues/313#issuecomment-617651698
|
||||
+ testImplementation 'junit:junit:4.12'
|
||||
+ androidTestImplementation 'androidx.test:runner:1.1.1'
|
||||
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
|
||||
implementation 'androidx.multidex:multidex:2.0.1'
|
||||
}
|
||||
|
||||
-//apply plugin: 'com.google.gms.google-services'
|
||||
+apply plugin: 'com.google.gms.google-services'
|
||||
diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro
|
||||
new file mode 100644
|
||||
index 00000000..40570865
|
||||
--- /dev/null
|
||||
+++ b/android/app/proguard-rules.pro
|
||||
@@ -0,0 +1,41 @@
|
||||
+-optimizationpasses 5
|
||||
+## Flutter wrapper
|
||||
+-keep class io.flutter.app.** { *; }
|
||||
+-keep class io.flutter.plugin.** { *; }
|
||||
+-keep class io.flutter.util.** { *; }
|
||||
+-keep class io.flutter.view.** { *; }
|
||||
+-keep class io.flutter.** { *; }
|
||||
+-keep class io.flutter.plugins.** { *; }
|
||||
+-dontwarn io.flutter.embedding.**
|
||||
+
|
||||
+##---------------Begin: proguard configuration for Gson (Needed for flutter_local_notifications) ----------
|
||||
+# Gson uses generic type information stored in a class file when working with fields. Proguard
|
||||
+# removes such information by default, so configure it to keep all of it.
|
||||
+-keepattributes Signature
|
||||
+
|
||||
+# For using GSON @Expose annotation
|
||||
+-keepattributes *Annotation*
|
||||
+
|
||||
+# Gson specific classes
|
||||
+-dontwarn sun.misc.**
|
||||
+
|
||||
+# Application classes that will be serialized/deserialized over Gson
|
||||
+-keep class com.google.gson.examples.android.model.** { <fields>; }
|
||||
+
|
||||
+# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
|
||||
+# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
|
||||
+-keep class * extends com.google.gson.TypeAdapter
|
||||
+-keep class * implements com.google.gson.TypeAdapterFactory
|
||||
+-keep class * implements com.google.gson.JsonSerializer
|
||||
+-keep class * implements com.google.gson.JsonDeserializer
|
||||
+
|
||||
+# Prevent R8 from leaving Data object members always null
|
||||
+-keepclassmembers,allowobfuscation class * {
|
||||
+ @com.google.gson.annotations.SerializedName <fields>;
|
||||
+}
|
||||
+
|
||||
+# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher.
|
||||
+-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
|
||||
+-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken
|
||||
+
|
||||
+##---------------End: proguard configuration for Gson (Needed for flutter_local_notifications) ----------
|
||||
\ No newline at end of file
|
||||
diff --git a/android/app/src/main/kotlin/chat/fluffy/fluffychat/FcmPushService.kt b/android/app/src/main/kotlin/chat/fluffy/fluffychat/FcmPushService.kt
|
||||
index d9930f55..510e9845 100644
|
||||
--- a/android/app/src/main/kotlin/chat/fluffy/fluffychat/FcmPushService.kt
|
||||
+++ b/android/app/src/main/kotlin/chat/fluffy/fluffychat/FcmPushService.kt
|
||||
@@ -1,4 +1,4 @@
|
||||
-/*package chat.fluffy.fluffychat
|
||||
+package chat.fluffy.fluffychat
|
||||
|
||||
import com.famedly.fcm_shared_isolate.FcmSharedIsolateService
|
||||
|
||||
@@ -33,4 +33,3 @@ class FcmPushService : FcmSharedIsolateService() {
|
||||
}
|
||||
}
|
||||
}
|
||||
-*/
|
||||
\ No newline at end of file
|
||||
diff --git a/android/app/src/main/kotlin/chat/fluffy/fluffychat/MainActivity.kt b/android/app/src/main/kotlin/chat/fluffy/fluffychat/MainActivity.kt
|
||||
index 1afc4606..894d1571 100644
|
||||
--- a/android/app/src/main/kotlin/chat/fluffy/fluffychat/MainActivity.kt
|
||||
+++ b/android/app/src/main/kotlin/chat/fluffy/fluffychat/MainActivity.kt
|
||||
@@ -7,13 +7,11 @@ import android.content.Context
|
||||
import androidx.multidex.MultiDex
|
||||
|
||||
class MainActivity : FlutterActivity() {
|
||||
-
|
||||
override fun attachBaseContext(base: Context) {
|
||||
super.attachBaseContext(base)
|
||||
MultiDex.install(this)
|
||||
}
|
||||
|
||||
-
|
||||
override fun provideFlutterEngine(context: Context): FlutterEngine? {
|
||||
return provideEngine(this)
|
||||
}
|
||||
diff --git a/android/build.gradle b/android/build.gradle
|
||||
index 85aa8647..3b7e09e7 100644
|
||||
--- a/android/build.gradle
|
||||
+++ b/android/build.gradle
|
||||
@@ -8,7 +8,7 @@ buildscript {
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.2.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
- //classpath 'com.google.gms:google-services:4.3.8'
|
||||
+ classpath 'com.google.gms:google-services:4.3.8'
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/lib/utils/background_push.dart b/lib/utils/background_push.dart
|
||||
index cd79b0ab..c2db0f1e 100644
|
||||
--- a/lib/utils/background_push.dart
|
||||
+++ b/lib/utils/background_push.dart
|
||||
@@ -39,7 +39,7 @@ import '../config/setting_keys.dart';
|
||||
import 'famedlysdk_store.dart';
|
||||
import 'platform_infos.dart';
|
||||
|
||||
-//import 'package:fcm_shared_isolate/fcm_shared_isolate.dart';
|
||||
+import 'package:fcm_shared_isolate/fcm_shared_isolate.dart';
|
||||
|
||||
class NoTokenException implements Exception {
|
||||
String get cause => 'Cannot get firebase token';
|
||||
@@ -65,7 +65,7 @@ class BackgroundPush {
|
||||
|
||||
final pendingTests = <String, Completer<void>>{};
|
||||
|
||||
- final dynamic firebase = null; //FcmSharedIsolate();
|
||||
+ final dynamic firebase = FcmSharedIsolate();
|
||||
|
||||
DateTime? lastReceivedPush;
|
||||
|
||||
diff --git a/pubspec.yaml b/pubspec.yaml
|
||||
index 6999d0b8..b2c9144f 100644
|
||||
--- a/pubspec.yaml
|
||||
+++ b/pubspec.yaml
|
||||
@@ -25,7 +25,7 @@ dependencies:
|
||||
email_validator: ^2.0.1
|
||||
emoji_picker_flutter: ^1.1.2
|
||||
encrypt: ^5.0.1
|
||||
- #fcm_shared_isolate: ^0.1.0
|
||||
+ fcm_shared_isolate: ^0.1.0
|
||||
file_picker_cross: ^4.6.0
|
||||
flutter:
|
||||
sdk: flutter
|
@ -1,5 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
git apply ./scripts/enable-android-google-services.patch
|
||||
cd android
|
||||
echo $FDROID_KEY | base64 --decode --ignore-garbage > key.jks
|
||||
echo "storePassword=${FDROID_KEY_PASS}" >> key.properties
|
||||
|
@ -1,5 +1,4 @@
|
||||
#!/bin/sh -ve
|
||||
git apply ./scripts/enable-android-google-services.patch
|
||||
flutter clean
|
||||
flutter pub get
|
||||
cd ios
|
||||
|
Loading…
x
Reference in New Issue
Block a user