feat(firebase): add production config and push token refresh listener
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "950566980029",
|
||||
"project_id": "sf-platform-pro",
|
||||
"storage_bucket": "sf-platform-pro.firebasestorage.app"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:950566980029:android:75a7c10b6259d09681aad4",
|
||||
"android_client_info": {
|
||||
"package_name": "com.savefamily.app"
|
||||
}
|
||||
},
|
||||
"oauth_client": [],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyDkjNdOAK0ype7wgdgiC1BCKV_pP4s_mlA"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": []
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"env": "production",
|
||||
"apiBaseUrl": "https://api-neki-b2b.neki.es/gateway/api/",
|
||||
"apiOrigin": "https://neki-b2b.neki.es",
|
||||
"wsUrl": "wss://api-neki-b2b.neki.es/websocket"
|
||||
}
|
||||
"apiBaseUrl": "https://platform.savefamily.app/gateway/api/",
|
||||
"apiOrigin": "https://api-platform.savefamily.app/",
|
||||
"wsUrl": "wss://api-platform.savefamily.app/websocket"
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
{"flutter":{"platforms":{"android":{"default":{"projectId":"sf-platform-pre","appId":"1:535646668726:android:b87245b807258e3e5e6317","fileOutput":"android/app/google-services.json"}},"ios":{"default":{"projectId":"sf-platform-pre","appId":"1:535646668726:ios:5172d626d02dfe215e6317","uploadDebugSymbols":true,"fileOutput":"ios/Runner/GoogleService-Info.plist"}},"dart":{"lib/firebase_options_dev.dart":{"projectId":"sf-platform-pre","configurations":{"android":"1:535646668726:android:c3a09d6c26f0cdf95e6317","ios":"1:535646668726:ios:524afa641f61d7cb5e6317"}},"lib/firebase_options_staging.dart":{"projectId":"sf-platform-pre","configurations":{"android":"1:535646668726:android:b87245b807258e3e5e6317","ios":"1:535646668726:ios:5172d626d02dfe215e6317"}}}}}}
|
||||
{"flutter":{"platforms":{"android":{"default":{"projectId":"sf-platform-pre","appId":"1:535646668726:android:b87245b807258e3e5e6317","fileOutput":"android/app/google-services.json"}},"ios":{"default":{"projectId":"sf-platform-pre","appId":"1:535646668726:ios:5172d626d02dfe215e6317","uploadDebugSymbols":true,"fileOutput":"ios/Runner/GoogleService-Info.plist"}},"dart":{"lib/firebase_options_dev.dart":{"projectId":"sf-platform-pre","configurations":{"android":"1:535646668726:android:c3a09d6c26f0cdf95e6317","ios":"1:535646668726:ios:524afa641f61d7cb5e6317"}},"lib/firebase_options_staging.dart":{"projectId":"sf-platform-pre","configurations":{"android":"1:535646668726:android:b87245b807258e3e5e6317","ios":"1:535646668726:ios:5172d626d02dfe215e6317"}},"lib/firebase_options_prod.dart":{"projectId":"sf-platform-pro","configurations":{"android":"1:950566980029:android:75a7c10b6259d09681aad4","ios":"1:950566980029:ios:987b4f0b9e9b897481aad4"}}}}}}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>API_KEY</key>
|
||||
<string>AIzaSyC0_d7Z6uVHHKhaf7JHRROaY6g2mvvpOXU</string>
|
||||
<key>GCM_SENDER_ID</key>
|
||||
<string>950566980029</string>
|
||||
<key>PLIST_VERSION</key>
|
||||
<string>1</string>
|
||||
<key>BUNDLE_ID</key>
|
||||
<string>com.savefamily.app</string>
|
||||
<key>PROJECT_ID</key>
|
||||
<string>sf-platform-pro</string>
|
||||
<key>STORAGE_BUCKET</key>
|
||||
<string>sf-platform-pro.firebasestorage.app</string>
|
||||
<key>IS_ADS_ENABLED</key>
|
||||
<false></false>
|
||||
<key>IS_ANALYTICS_ENABLED</key>
|
||||
<false></false>
|
||||
<key>IS_APPINVITE_ENABLED</key>
|
||||
<true></true>
|
||||
<key>IS_GCM_ENABLED</key>
|
||||
<true></true>
|
||||
<key>IS_SIGNIN_ENABLED</key>
|
||||
<true></true>
|
||||
<key>GOOGLE_APP_ID</key>
|
||||
<string>1:950566980029:ios:987b4f0b9e9b897481aad4</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -7,6 +7,7 @@ import 'package:flutter/foundation.dart';
|
||||
|
||||
import '../config/env/environment_enum.dart';
|
||||
import '../firebase_options_dev.dart' as dev_options;
|
||||
import '../firebase_options_prod.dart' as prod_options;
|
||||
import '../firebase_options_staging.dart' as staging_options;
|
||||
import 'app_version_check/remote_config_keys.dart';
|
||||
|
||||
@@ -18,12 +19,7 @@ Future<void> setupFirebase(EnvironmentEnum env) async {
|
||||
case EnvironmentEnum.staging:
|
||||
options = staging_options.DefaultFirebaseOptions.currentPlatform;
|
||||
case EnvironmentEnum.production:
|
||||
// TODO: replace with prod_options.DefaultFirebaseOptions.currentPlatform
|
||||
// once the production Firebase project is created.
|
||||
throw UnsupportedError(
|
||||
'Production Firebase project is not configured yet. '
|
||||
'Run `flutterfire configure --project=<prod-project-id>` and import it here.',
|
||||
);
|
||||
options = prod_options.DefaultFirebaseOptions.currentPlatform;
|
||||
}
|
||||
|
||||
await Firebase.initializeApp(options: options);
|
||||
@@ -54,7 +50,7 @@ Future<void> setupFirebase(EnvironmentEnum env) async {
|
||||
RemoteConfigKeys.latestBuild: 0,
|
||||
RemoteConfigKeys.updateForce: false,
|
||||
RemoteConfigKeys.updateMessage: '',
|
||||
RemoteConfigKeys.updateUrlIos: 'https://apps.apple.com/app/id6759873957',
|
||||
RemoteConfigKeys.updateUrlIos: 'https://apps.apple.com/app/id6759875039',
|
||||
RemoteConfigKeys.updateUrlAndroid:
|
||||
'https://play.google.com/store/apps/details?id=com.savefamily.app',
|
||||
});
|
||||
|
||||
@@ -56,11 +56,6 @@ Future<void> setupNotifications() async {
|
||||
_onMessageOpenedApp(initialMessage);
|
||||
}
|
||||
|
||||
// TODO: integrate with backend (Treezor/SaveFamily api).
|
||||
messaging.onTokenRefresh.listen((newToken) {
|
||||
debugPrint('[FCM] token refreshed: $newToken');
|
||||
});
|
||||
|
||||
try {
|
||||
final token = await messaging.getToken();
|
||||
debugPrint('[FCM] initial token: $token');
|
||||
|
||||
68
apps/mobile_app/lib/firebase_options_prod.dart
Normal file
68
apps/mobile_app/lib/firebase_options_prod.dart
Normal file
@@ -0,0 +1,68 @@
|
||||
// File generated by FlutterFire CLI.
|
||||
// ignore_for_file: type=lint
|
||||
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
|
||||
import 'package:flutter/foundation.dart'
|
||||
show defaultTargetPlatform, kIsWeb, TargetPlatform;
|
||||
|
||||
/// Default [FirebaseOptions] for use with your Firebase apps.
|
||||
///
|
||||
/// Example:
|
||||
/// ```dart
|
||||
/// import 'firebase_options_prod.dart';
|
||||
/// // ...
|
||||
/// await Firebase.initializeApp(
|
||||
/// options: DefaultFirebaseOptions.currentPlatform,
|
||||
/// );
|
||||
/// ```
|
||||
class DefaultFirebaseOptions {
|
||||
static FirebaseOptions get currentPlatform {
|
||||
if (kIsWeb) {
|
||||
throw UnsupportedError(
|
||||
'DefaultFirebaseOptions have not been configured for web - '
|
||||
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||
);
|
||||
}
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.android:
|
||||
return android;
|
||||
case TargetPlatform.iOS:
|
||||
return ios;
|
||||
case TargetPlatform.macOS:
|
||||
throw UnsupportedError(
|
||||
'DefaultFirebaseOptions have not been configured for macos - '
|
||||
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||
);
|
||||
case TargetPlatform.windows:
|
||||
throw UnsupportedError(
|
||||
'DefaultFirebaseOptions have not been configured for windows - '
|
||||
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||
);
|
||||
case TargetPlatform.linux:
|
||||
throw UnsupportedError(
|
||||
'DefaultFirebaseOptions have not been configured for linux - '
|
||||
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||
);
|
||||
default:
|
||||
throw UnsupportedError(
|
||||
'DefaultFirebaseOptions are not supported for this platform.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static const FirebaseOptions android = FirebaseOptions(
|
||||
apiKey: 'AIzaSyDkjNdOAK0ype7wgdgiC1BCKV_pP4s_mlA',
|
||||
appId: '1:950566980029:android:75a7c10b6259d09681aad4',
|
||||
messagingSenderId: '950566980029',
|
||||
projectId: 'sf-platform-pro',
|
||||
storageBucket: 'sf-platform-pro.firebasestorage.app',
|
||||
);
|
||||
|
||||
static const FirebaseOptions ios = FirebaseOptions(
|
||||
apiKey: 'AIzaSyC0_d7Z6uVHHKhaf7JHRROaY6g2mvvpOXU',
|
||||
appId: '1:950566980029:ios:987b4f0b9e9b897481aad4',
|
||||
messagingSenderId: '950566980029',
|
||||
projectId: 'sf-platform-pro',
|
||||
storageBucket: 'sf-platform-pro.firebasestorage.app',
|
||||
iosBundleId: 'com.savefamily.app',
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:auth/auth.dart';
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
@@ -72,6 +73,9 @@ class SaveFamilyAppState extends ConsumerState<SaveFamilyApp>
|
||||
_walletHeartbeat?.stop();
|
||||
_legacyHeartbeat?.stop();
|
||||
_webSocket?.disconnect();
|
||||
FirebaseMessaging.instance.deleteToken().catchError((Object e) {
|
||||
debugPrint('[FCM] deleteToken on logout failed: $e');
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -124,6 +128,7 @@ class SaveFamilyAppState extends ConsumerState<SaveFamilyApp>
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
SizeUtils.init(context: context);
|
||||
ref.watch(pushTokenRefreshListenerProvider);
|
||||
|
||||
return AppUpdateGate(
|
||||
child: MaterialApp.router(
|
||||
|
||||
@@ -32,6 +32,7 @@ export 'src/data/datasource/user_remote_datasource_impl.dart';
|
||||
export 'src/data/datasource/notifications_remote_datasource.dart';
|
||||
export 'src/data/datasource/notifications_remote_datasource_impl.dart';
|
||||
export 'src/providers/notifications_remote_datasource_provider.dart';
|
||||
export 'src/providers/push_token_refresh_listener_provider.dart';
|
||||
export 'src/domain/entities/beneficiary_validation_entity.dart';
|
||||
export 'src/domain/entities/transaction_beneficiary_entity.dart';
|
||||
export 'src/data/models/payout_beneficiary_model.dart';
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import 'notifications_remote_datasource_provider.dart';
|
||||
|
||||
final pushTokenRefreshListenerProvider = Provider<void>((ref) {
|
||||
final datasource = ref.watch(notificationsRemoteDatasourceProvider);
|
||||
final subscription = FirebaseMessaging.instance.onTokenRefresh.listen((
|
||||
newToken,
|
||||
) async {
|
||||
try {
|
||||
await datasource.registerPushToken(newToken);
|
||||
debugPrint('[FCM] token refreshed and re-registered: $newToken');
|
||||
} catch (e) {
|
||||
debugPrint('[FCM] token refresh re-register failed: $e');
|
||||
}
|
||||
});
|
||||
ref.onDispose(subscription.cancel);
|
||||
});
|
||||
Reference in New Issue
Block a user