Bladeren bron

android notification done

master
amin 1 jaar geleden
bovenliggende
commit
8039bbf63a
21 gewijzigde bestanden met toevoegingen van 430 en 157 verwijderingen
  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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

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

list(APPEND FLUTTER_PLUGIN_LIST
firebase_core
permission_handler_windows
)



Laden…
Annuleren
Opslaan