Explorar el Código

android notification done

master
amin hace 1 año
padre
commit
8039bbf63a
Se han modificado 21 ficheros con 430 adiciones y 157 borrados
  1. +5
    -0
      android/app/build.gradle
  2. +29
    -0
      android/app/google-services.json
  3. +12
    -6
      android/app/src/main/AndroidManifest.xml
  4. +3
    -0
      android/settings.gradle
  5. +50
    -0
      ios/Runner/AppDelegate.swift
  6. +30
    -0
      ios/Runner/GoogleService-Info.plist
  7. +60
    -20
      lib/main.dart
  8. +3
    -1
      lib/screens/auth/login_screen.dart
  9. +4
    -2
      lib/screens/auth/otp_screen.dart
  10. +5
    -4
      lib/screens/auth/state/state.dart
  11. +103
    -112
      lib/screens/home/screen.dart
  12. +3
    -2
      lib/screens/meeting/screen.dart
  13. +3
    -4
      lib/screens/private_meeting/screen.dart
  14. +3
    -2
      lib/screens/report/screen.dart
  15. +10
    -4
      lib/services/auth/auth.dart
  16. +40
    -0
      lib/services/notification/notification_service.dart
  17. +4
    -0
      macos/Flutter/GeneratedPluginRegistrant.swift
  18. +56
    -0
      pubspec.lock
  19. +3
    -0
      pubspec.yaml
  20. +3
    -0
      windows/flutter/generated_plugin_registrant.cc
  21. +1
    -0
      windows/flutter/generated_plugins.cmake

+ 5
- 0
android/app/build.gradle Ver fichero

@@ -1,5 +1,8 @@
plugins {
id "com.android.application"
// START: FlutterFire Configuration
id 'com.google.gms.google-services'
// END: FlutterFire Configuration
id "kotlin-android"
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id "dev.flutter.flutter-gradle-plugin"
@@ -42,3 +45,5 @@ android {
flutter {
source = "../.."
}

apply plugin: 'com.google.gms.google-services'

+ 29
- 0
android/app/google-services.json Ver fichero

@@ -0,0 +1,29 @@
{
"project_info": {
"project_number": "392489806594",
"project_id": "folad-neiriz",
"storage_bucket": "folad-neiriz.firebasestorage.app"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:392489806594:android:76b6661258b6f56f3b301b",
"android_client_info": {
"package_name": "com.example.qadirneyriz"
}
},
"oauth_client": [],
"api_key": [
{
"current_key": "AIzaSyAuDK456j4fFdNqrzQRDYyWRcB0VkQ2bCY"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": []
}
}
}
],
"configuration_version": "1"
}

+ 12
- 6
android/app/src/main/AndroidManifest.xml Ver fichero

@@ -1,10 +1,12 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application
android:label="Mizban"
android:name="${applicationName}"
@@ -18,10 +20,6 @@
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
@@ -31,11 +29,19 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service
android:name="io.flutter.plugins.firebase.messaging.FlutterFirebaseMessagingService"
android:exported="true"
tools:replace="android:exported">
</service>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="high_importance_channel" />
</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and


+ 3
- 0
android/settings.gradle Ver fichero

@@ -19,6 +19,9 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.1.0" apply false
// START: FlutterFire Configuration
id "com.google.gms.google-services" version "4.3.15" apply false
// END: FlutterFire Configuration
id "org.jetbrains.kotlin.android" version "1.8.22" apply false
}



+ 50
- 0
ios/Runner/AppDelegate.swift Ver fichero

@@ -1,5 +1,7 @@
import Flutter
import UIKit
import Firebase
import FirebaseMessaging

@main
@objc class AppDelegate: FlutterAppDelegate {
@@ -7,7 +9,55 @@ import UIKit
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// مقداردهی Firebase
FirebaseApp.configure()
// ثبت Plugin های Flutter
GeneratedPluginRegistrant.register(with: self)

// تنظیمات Notification Center
UNUserNotificationCenter.current().delegate = self
Messaging.messaging().delegate = self

// درخواست مجوز نوتیفیکیشن
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in
if let error = error {
print("Error requesting notification permissions: \(error)")
}
print("Permission granted: \(granted)")
}
// ثبت دستگاه برای دریافت Remote Notifications
application.registerForRemoteNotifications()
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

// متد دریافت APNs Token و ارسال آن به Firebase
override func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
Messaging.messaging().apnsToken = deviceToken
}
}

// افزودن پروتکل‌های UNUserNotificationCenterDelegate و MessagingDelegate
extension AppDelegate: UNUserNotificationCenterDelegate, MessagingDelegate {
// مدیریت دریافت توکن Firebase
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
print("Firebase FCM Token: \(fcmToken ?? "No Token")")
// اگر نیاز به ارسال توکن به سرور دارید، اینجا انجام دهید.
}
// مدیریت پیام‌های دریافت‌شده هنگام باز بودن اپلیکیشن
func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
) {
let userInfo = notification.request.content.userInfo
print("Foreground Notification Received: \(userInfo)")
completionHandler([.banner, .sound, .badge])
}
}

+ 30
- 0
ios/Runner/GoogleService-Info.plist Ver fichero

@@ -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>AIzaSyDmiLNq_t5wyqDE2VW1wGyt6kArchRvLAQ</string>
<key>GCM_SENDER_ID</key>
<string>392489806594</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.example.qadirneyriz</string>
<key>PROJECT_ID</key>
<string>folad-neiriz</string>
<key>STORAGE_BUCKET</key>
<string>folad-neiriz.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:392489806594:ios:feeba2107eb852ec3b301b</string>
</dict>
</plist>

+ 60
- 20
lib/main.dart Ver fichero

@@ -1,3 +1,5 @@
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:hive_flutter/hive_flutter.dart';
@@ -13,9 +15,52 @@ import 'package:qadirneyriz/screens/private_meeting/state.dart';
import 'package:qadirneyriz/screens/report/state.dart';
import 'package:qadirneyriz/setting/setting.dart';

void main() async {
final FirebaseMessaging messaging = FirebaseMessaging.instance;

Future<void> initializeApp() async {
await Firebase.initializeApp();
await Hive.initFlutter();
await setting.userLocalDb.openBox();
await requestNotificationPermission();
await getToken();
setupMessageListener();
}

Future<void> requestNotificationPermission() async {
NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);

if (settings.authorizationStatus == AuthorizationStatus.authorized) {
print('User granted permission');
} else {
print('User declined or has not granted permission');
}
}

Future<void> getToken() async {
String? token = await messaging.getToken();
print("Device Token: $token");
// You can send the token to your server here if needed
}

void setupMessageListener() {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('Message received: ${message.notification?.title}');
print('Message body: ${message.notification?.body}');
// You can use a Dialog or Toast to display the message here
});
}

void main() async {
WidgetsFlutterBinding.ensureInitialized();
await initializeApp(); // Initialize Firebase and other services
runApp(
MultiProvider(
providers: [
@@ -41,51 +86,46 @@ class MyApp extends StatefulWidget {
class _MyAppState extends State<MyApp> {
late AuthState state;
String language = setting.userLocalDb.getUser().language;

@override
void initState() {
super.initState();
Future.delayed(Duration.zero, () async {
state = Provider.of(context, listen: false);
state = Provider.of<AuthState>(context, listen: false);
setState(() {
language = state.language;
});
});
super.initState();
}

// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return Consumer<AuthState>(
builder: (context, value, child) {
return MaterialApp.router(
theme: ThemeData(
colorScheme: ColorScheme.light(
// تغییر رنگ اصلی تایم پیکر
primary: config.ui.mainGreen,
// تغییر رنگ متن
),
buttonTheme: ButtonThemeData(
colorScheme: ColorScheme.light(
primary: Colors.green, // رنگ دکمه‌ها
),
),
useMaterial3: true,
fontFamily: 'Font',
scaffoldBackgroundColor: Colors.white),
colorScheme: ColorScheme.light(primary: config.ui.mainGreen),
buttonTheme: ButtonThemeData(
colorScheme: ColorScheme.light(primary: Colors.green),
),
useMaterial3: true,
fontFamily: 'Font',
scaffoldBackgroundColor: Colors.white,
),
debugShowCheckedModeBanner: false,
routerDelegate: router.routerDelegate,
routeInformationParser: router.routeInformationParser,
routeInformationProvider: router.routeInformationProvider,
localizationsDelegates: const [
AppLocalizations.delegate, // Add this line
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
locale: Locale(value.language),
supportedLocales: const [
Locale('en'), // English
Locale('fa'), // Persian
Locale('en'),
Locale('fa'),
],
);
},


+ 3
- 1
lib/screens/auth/login_screen.dart Ver fichero

@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:qadirneyriz/config/config.dart';
import 'package:qadirneyriz/main.dart';
import 'package:qadirneyriz/screens/auth/state/state.dart';
import 'package:qadirneyriz/utils/enums/status.dart';
import 'package:qadirneyriz/utils/tools/tools.dart';
@@ -151,8 +152,9 @@ class _LoginScreenState extends State<LoginScreen> {
isError: true,
context,
);
} else {
} else { String? token = await messaging.getToken();
final status = await state.login(
fcm_token: token??'',
mobile: phoneController.text,
password: passwordController.text);
if (status == Status.ready) {


+ 4
- 2
lib/screens/auth/otp_screen.dart Ver fichero

@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:qadirneyriz/config/config.dart';
import 'package:qadirneyriz/main.dart';
import 'package:qadirneyriz/screens/auth/state/state.dart';
import 'package:qadirneyriz/utils/enums/status.dart';
import 'package:qadirneyriz/utils/timer/apt_simple_timer_with_controller.dart';
@@ -182,9 +183,10 @@ class _OtpScreenState extends State<OtpScreen> {
}

void otpCheckCode(onSubmitted, AuthState value) async {
String? token = await messaging.getToken();
if (onSubmitted.length == 4) {
final status =
await value.login(mobile: widget.phoneNumber, otp: onSubmitted);
final status = await value.login(
mobile: widget.phoneNumber, otp: onSubmitted, fcm_token: token ?? '');
if (status == Status.ready) {
context.goNamed('navigate', pathParameters: {'tab': '0'});
} else if (status == Status.error) {


+ 5
- 4
lib/screens/auth/state/state.dart Ver fichero

@@ -22,13 +22,16 @@ class AuthState extends ChangeNotifier {
Map? errorsLogin;

Future<Status> login(
{required String mobile, String? password, String? otp}) async {
{required String mobile,
String? password,
String? otp,
required String fcm_token}) async {
assert(password != null || otp != null);
statusLogin = Status.loading;
notifyListeners();
try {
final result = await authServises.loginApi(
mobile: mobile, password: password, otp: otp);
mobile: mobile, password: password, otp: otp, fcm_token: fcm_token);
if (result == null) {
statusLogin = Status.error;
} else {
@@ -88,6 +91,4 @@ class AuthState extends ChangeNotifier {
// print(statusSendotp);
return statusSendotp;
}


}

+ 103
- 112
lib/screens/home/screen.dart Ver fichero

@@ -38,8 +38,9 @@ class _HomeScreenState extends State<HomeScreen> {
@override
Widget build(BuildContext context) {
DateTime now = DateTime.now();
String dateMiladi =
Tools.convertToPersianDigits(DateFormat('yyyy-MM-dd').format(now));
String dateMiladi = setting.userLocalDb.getUser().language == 'fa'
? Tools.convertToPersianDigits(DateFormat('yyyy-MM-dd').format(now))
: DateFormat('yyyy-MM-dd').format(now);
String dateJalali = Tools.convertToPersianDigits(
'${setting.timeNow.day} ${Tools.getMonthName(setting.timeNow.month)} ${setting.timeNow.year}');

@@ -123,29 +124,38 @@ class _HomeScreenState extends State<HomeScreen> {
final meeting = value
.todayMeetingsModel!.meetings![index];
return Padding(
padding: const EdgeInsets.only(
right: 5, left: 1),
child: Stack(
children: [
CustomCardMeeting(
status: meeting.accepted ?? 0,
titel: meeting.subject != null
? meeting.subject!.subject ?? ''
: '',
fromTime: meeting.azHour ?? '',
toTime: meeting.taHour ?? "",
location: meeting.location != null
? meeting.location!.address ?? ''
: '',
date: meeting.dateJalali ?? '',
cardId: meeting.id ?? 0,
),
Positioned(
child: Container(
padding: const EdgeInsets.only(
right: 5, left: 1),
child: Stack(
children: [
CustomCardMeeting(
status: meeting.accepted ?? 0,
titel: meeting.subject != null
? meeting.subject!.subject ?? ''
: '',
fromTime: meeting.azHour ?? '',
toTime: meeting.taHour ?? "",
location: meeting.location != null
? meeting.location!.address ??
''
: '',
date: meeting.dateJalali ?? '',
cardId: meeting.id ?? 0,
),
Positioned(
left: setting.userLocalDb
.getUser()
.language ==
'fa'
? 20
: 280,
top: 20,
child: Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(10),
color: Colors.green),
borderRadius:
BorderRadius.circular(10),
color: Colors.green,
),
child: Padding(
padding:
const EdgeInsets.all(5.0),
@@ -156,13 +166,11 @@ class _HomeScreenState extends State<HomeScreen> {
fontSize: 12,
color: Colors.white),
),
)),
left: 30,
top: 20,
),
],
),
);
),
),
),
],
));
} else {
// آیتم از لیست `privateMeetings`
final privateMeeting = value
@@ -192,6 +200,12 @@ class _HomeScreenState extends State<HomeScreen> {
toTime: privateMeeting.taHour ?? '',
),
Positioned(
left: setting.userLocalDb
.getUser()
.language ==
'fa'
? 20
: 250,
child: Container(
decoration: BoxDecoration(
borderRadius:
@@ -208,7 +222,6 @@ class _HomeScreenState extends State<HomeScreen> {
color: Colors.white),
),
)),
left: 30,
top: 20,
),
],
@@ -343,86 +356,7 @@ class _HomeScreenState extends State<HomeScreen> {
const SizedBox(
height: 30,
),
Consumer<HomeState>(
builder: (context, value, child) {
switch (value.statusLogOut) {
case Status.loading:
return const LoadingWidget();

default:
return Row(
mainAxisAlignment:
MainAxisAlignment
.center,
crossAxisAlignment:
CrossAxisAlignment
.center,
children: [
CustomButton(
fontSize: 13,
color: config
.ui.mainGreen,
onPressed: () {
Navigator.pop(
context);
},
hieght: 50,

// width: 150,
text: AppLocalizations
.of(context)!
.no,
),
const SizedBox(
width: 10,
),
CustomButton(
fontSize: 13,
hieght: 50,
// width: 150,
text: AppLocalizations
.of(context)!
.logout,
textColor:
Colors.black,
color: const Color(
0xffD0D5ED),

onPressed: () async {
final status =
await value
.logOut();
if (status ==
Status.error) {
Tools.showCustomSnackBar(
context,
text: value
.messageLogOut ??
AppLocalizations.of(
context)!
.error,
isError:
true);
} else if (status ==
Status.ready) {
context
.pushReplacementNamed(
'login');
Tools.showCustomSnackBar(
context,
text: value
.messageLogOut ??
'Done successfully',
isError:
false);
}
},
),
],
);
}
},
),
logOutButton(),
const SizedBox(
height: 40,
)
@@ -458,6 +392,63 @@ class _HomeScreenState extends State<HomeScreen> {
},
);
}

Consumer<HomeState> logOutButton() {
return Consumer<HomeState>(
builder: (context, value, child) {
switch (value.statusLogOut) {
case Status.loading:
return const LoadingWidget();

default:
return Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
CustomButton(
fontSize: 13,
color: config.ui.mainGreen,
onPressed: () {
Navigator.pop(context);
},
hieght: 50,

// width: 150,
text: AppLocalizations.of(context)!.no,
),
const SizedBox(
width: 10,
),
CustomButton(
fontSize: 13,
hieght: 50,
// width: 150,
text: AppLocalizations.of(context)!.logout,
textColor: Colors.black,
color: const Color(0xffD0D5ED),

onPressed: () async {
final status = await value.logOut();
if (status == Status.error) {
Tools.showCustomSnackBar(context,
text: value.messageLogOut ??
AppLocalizations.of(context)!.error,
isError: true);
} else if (status == Status.ready) {
setting.userLocalDb.logOut();
context.pushReplacementNamed('login');
Tools.showCustomSnackBar(context,
text: value.messageLogOut ?? 'Done successfully',
isError: false);
}
},
),
],
);
}
},
);
}
}

class ItemInGrid extends StatelessWidget {


+ 3
- 2
lib/screens/meeting/screen.dart Ver fichero

@@ -67,8 +67,9 @@ class _MeetingsScreenState extends State<MeetingsScreen> {
@override
Widget build(BuildContext context) {
DateTime now = DateTime.now();
String dateMiladi =
Tools.convertToPersianDigits(DateFormat('yyyy-MM-dd').format(now));
String dateMiladi = setting.userLocalDb.getUser().language == 'fa'
? Tools.convertToPersianDigits(DateFormat('yyyy-MM-dd').format(now))
: DateFormat('yyyy-MM-dd').format(now);
String dateJalali = Tools.convertToPersianDigits(
'${setting.timeNow.day} ${Tools.getMonthName(setting.timeNow.month)} ${setting.timeNow.year}');
// فرمت کردن تاریخ


+ 3
- 4
lib/screens/private_meeting/screen.dart Ver fichero

@@ -64,8 +64,9 @@ class _PrivateMeetingsScreenState extends State<PrivateMeetingsScreen> {
@override
Widget build(BuildContext context) {
DateTime now = DateTime.now();
String dateMiladi =
Tools.convertToPersianDigits(DateFormat('yyyy-MM-dd').format(now));
String dateMiladi = setting.userLocalDb.getUser().language == 'fa'
? Tools.convertToPersianDigits(DateFormat('yyyy-MM-dd').format(now))
: DateFormat('yyyy-MM-dd').format(now);
String dateJalali = Tools.convertToPersianDigits(
'${setting.timeNow.day} ${Tools.getMonthName(setting.timeNow.month)} ${setting.timeNow.year}');

@@ -315,8 +316,6 @@ class PrivateMeetingWidget extends StatelessWidget {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15),
child: Container(
width: 500,
height: 190,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [


+ 3
- 2
lib/screens/report/screen.dart Ver fichero

@@ -30,8 +30,9 @@ class _ReportScreenState extends State<ReportScreen> {
@override
Widget build(BuildContext context) {
DateTime now = DateTime.now();
String dateMiladi =
Tools.convertToPersianDigits(DateFormat('yyyy-MM-dd').format(now));
String dateMiladi = setting.userLocalDb.getUser().language == 'fa'
? Tools.convertToPersianDigits(DateFormat('yyyy-MM-dd').format(now))
: DateFormat('yyyy-MM-dd').format(now);
String dateJalali = Tools.convertToPersianDigits(
'${setting.timeNow.day} ${Tools.getMonthName(setting.timeNow.month)} ${setting.timeNow.year}');
// فرمت کردن تاریخ


+ 10
- 4
lib/services/auth/auth.dart Ver fichero

@@ -5,15 +5,20 @@ import 'package:qadirneyriz/utils/result/result.dart';

class AuthServices {
Future<Result?> loginApi(
{required String mobile, String? password, String? otp}) async {
{required String mobile,
String? password,
String? otp,
required String fcm_token}) async {
assert(password != null || otp != null);
try {
Map<String, String> headers = {"Accept": "application/json"};
FormData? formData;
formData = password != null
? FormData.fromMap({"mobile": mobile, "password": password})
: FormData.fromMap({"mobile": mobile, "otp": otp});

? FormData.fromMap(
{"mobile": mobile, "password": password, "device_id": fcm_token})
: FormData.fromMap(
{"mobile": mobile, "otp": otp, "device_id": fcm_token});
print('${formData.fields} resData');
final res = await Dio().post("${config.network.baseUrl}login",
data: formData, options: Options(headers: headers));

@@ -26,6 +31,7 @@ class AuthServices {
return Result(isOk: true, message: res.data['msg']);
}
} on DioException catch (e) {
print(e);
return Result(
isOk: false,
errors: e.response!.data['errors'],


+ 40
- 0
lib/services/notification/notification_service.dart Ver fichero

@@ -0,0 +1,40 @@
import 'package:firebase_messaging/firebase_messaging.dart';

class NotificationService {
final FirebaseMessaging _messaging = FirebaseMessaging.instance;

/// درخواست دسترسی به نوتیفیکیشن
Future<void> requestNotificationPermission() async {
NotificationSettings settings = await _messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);

if (settings.authorizationStatus == AuthorizationStatus.authorized) {
print('User granted permission');
} else {
print('User declined or has not granted permission');
}
}

/// دریافت توکن دستگاه
Future<void> getToken() async {
String? token = await _messaging.getToken();
print("Device Token: $token");
// اینجا می‌توانید توکن را به سرور خود ارسال کنید
}

/// تنظیم Listener برای دریافت نوتیفیکیشن‌ها
void setupMessageListener() {
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('Message received: ${message.notification?.title}');
print('Message body: ${message.notification?.body}');
// اینجا می‌توانید یک Dialog یا Toast برای نمایش پیام استفاده کنید
});
}
}

+ 4
- 0
macos/Flutter/GeneratedPluginRegistrant.swift Ver fichero

@@ -5,11 +5,15 @@
import FlutterMacOS
import Foundation

import firebase_core
import firebase_messaging
import open_file_mac
import path_provider_foundation
import sqflite

func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin"))
OpenFilePlugin.register(with: registry.registrar(forPlugin: "OpenFilePlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))


+ 56
- 0
pubspec.lock Ver fichero

@@ -9,6 +9,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "72.0.0"
_flutterfire_internals:
dependency: transitive
description:
name: _flutterfire_internals
sha256: "71c01c1998c40b3af1944ad0a5f374b4e6fef7f3d2df487f3970dbeadaeb25a1"
url: "https://pub.dev"
source: hosted
version: "1.3.46"
_macros:
dependency: transitive
description: dart
@@ -262,6 +270,54 @@ packages:
url: "https://pub.dev"
source: hosted
version: "8.1.3"
firebase_core:
dependency: "direct main"
description:
name: firebase_core
sha256: "2438a75ad803e818ad3bd5df49137ee619c46b6fc7101f4dbc23da07305ce553"
url: "https://pub.dev"
source: hosted
version: "3.8.0"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
sha256: e30da58198a6d4b49d5bce4e852f985c32cb10db329ebef9473db2b9f09ce810
url: "https://pub.dev"
source: hosted
version: "5.3.0"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
sha256: f967a7138f5d2ffb1ce15950e2a382924239eaa521150a8f144af34e68b3b3e5
url: "https://pub.dev"
source: hosted
version: "2.18.1"
firebase_messaging:
dependency: "direct main"
description:
name: firebase_messaging
sha256: "4d0968ecb860d7baa15a6e2af3469ec5b0d959e51c59ce84a52b0f7632a4aa5a"
url: "https://pub.dev"
source: hosted
version: "15.1.5"
firebase_messaging_platform_interface:
dependency: transitive
description:
name: firebase_messaging_platform_interface
sha256: a2cb3e7d71d40b6612e2d4e0daa0ae759f6a9d07f693f904d14d22aadf70be10
url: "https://pub.dev"
source: hosted
version: "4.5.48"
firebase_messaging_web:
dependency: transitive
description:
name: firebase_messaging_web
sha256: "1554e190f0cd9d6fe59f61ae0275ac12006fdb78b07669f1a260d1a9e6de3a1f"
url: "https://pub.dev"
source: hosted
version: "3.9.4"
fixnum:
dependency: transitive
description:


+ 3
- 0
pubspec.yaml Ver fichero

@@ -34,6 +34,9 @@ dependencies:
file_picker: ^8.1.3
permission_handler: ^11.3.1
open_file: ^3.5.9
firebase_core: ^3.8.0
firebase_messaging: ^15.1.5


dev_dependencies:
flutter_test:


+ 3
- 0
windows/flutter/generated_plugin_registrant.cc Ver fichero

@@ -6,9 +6,12 @@

#include "generated_plugin_registrant.h"

#include <firebase_core/firebase_core_plugin_c_api.h>
#include <permission_handler_windows/permission_handler_windows_plugin.h>

void RegisterPlugins(flutter::PluginRegistry* registry) {
FirebaseCorePluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
PermissionHandlerWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
}

+ 1
- 0
windows/flutter/generated_plugins.cmake Ver fichero

@@ -3,6 +3,7 @@
#

list(APPEND FLUTTER_PLUGIN_LIST
firebase_core
permission_handler_windows
)



Cargando…
Cancelar
Guardar