Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

background fetch not running when app is closed #382

Closed
zsrour1991 opened this issue Oct 22, 2024 · 5 comments
Closed

background fetch not running when app is closed #382

zsrour1991 opened this issue Oct 22, 2024 · 5 comments
Labels

Comments

@zsrour1991
Copy link

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:ess_application/appservices_lib.dart';
import 'package:ess_core/esscore_lib.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:get_it/get_it.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:background_fetch/background_fetch.dart';

class BackGroundHelper {
late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
late Timer _timer;

BackGroundHelper() {
initializeNotifications();
initBackgroundFetch();
//registration();
startTimer(); // Start the timer here
}
static late NotificationService notificationService =
locator(); // Declare NotificationService

static GetIt sl = GetIt.instance;

Future initializeNotifications() async {
print("initializeNotifications");
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();

const AndroidInitializationSettings initializationSettingsAndroid =
    AndroidInitializationSettings('@mipmap/ic_launcher');

const InitializationSettings initializationSettings =
    InitializationSettings(
  android: initializationSettingsAndroid,
  iOS: DarwinInitializationSettings(),
);

await flutterLocalNotificationsPlugin.initialize(initializationSettings,
    onDidReceiveNotificationResponse: (NotificationResponse response) {
  print("Notification tapped: ${response.payload}");
});

// Create notification channel
_createNotificationChannel();

// For iOS, request permission
if (Platform.isIOS) {
  final permissionGranted = await flutterLocalNotificationsPlugin
      .resolvePlatformSpecificImplementation<
          IOSFlutterLocalNotificationsPlugin>()
      ?.requestPermissions(
        alert: true,
        badge: true,
        sound: true,
      );
  print('Permission granted: $permissionGranted');
}

}

Future _createNotificationChannel() async {
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'your_channel_id', // Unique ID for the channel
'your_channel_name', // User-visible name for the channel
description: 'your_channel_description', // Description for the channel
importance: Importance.max, // Importance level for notifications
playSound: true, // Play sound for notifications
);
await requestPermissions();
flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
}

Future showNotification() async {
print("Showing notification...");
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'your_channel_id', // Ensure this matches the channel ID used in _createNotificationChannel
'your_channel_name',
channelDescription: 'your_channel_description',
importance: Importance.max,
priority: Priority.high,
playSound: true, // Ensure this is set if you want sound
);
var platformChannelSpecifics = NotificationDetails(
android: androidPlatformChannelSpecifics,
iOS: DarwinNotificationDetails(),
);

try {
  print("fetch notification");
  SharedPreferences sp = await SharedPreferences.getInstance();

  if (sp.getInt('companyId') != null) {
    print("fetch notification");
    print(sp.getInt('companyId'));
    await notificationService.fetch().then((value) async {
      print("Fetching notifications");
      print(notificationService.state.notificationsUnseen.length);
      if (notificationService.state.notificationsUnseen.isNotEmpty) {
        print("----------------------");
        // if(sp.getInt("notificationId")!=notificationService.state.notificationsUnseen[0].id!){
        sp.setInt("notificationId",
            notificationService.state.notificationsUnseen[0].id!);
        await flutterLocalNotificationsPlugin.show(
          notificationService.state.notificationsUnseen[0].id!,
          "${changeTime(notificationService.state.notificationsUnseen[0].dateCreated!, 6, true)} ${notificationService.state.notificationsUnseen[0].companyName!}",
          notificationService.state.notificationsUnseen[0].text!,
          const NotificationDetails(
            android: AndroidNotificationDetails(
                'your_channel_id', 'your_channel_name',
                channelDescription: 'your_channel_description',
                importance: Importance.max,
                icon: '@mipmap/ic_launcher'),
            iOS: DarwinNotificationDetails(),
          ),
          payload: jsonEncode({
            'id': notificationService.state.notificationsUnseen[0].id,
            'companyName': notificationService
                .state.notificationsUnseen[0].companyName,
          }),
        ); //}
      }
    });
  }

  print("Notification displayed successfully.");
} catch (e) {
  print("Error displaying notification: $e");
}

}

static Future requestPermissions() async {
if (Platform.isAndroid) {
var status = await Permission.notification.status;
if (!status.isGranted) {
await Permission.notification.request();
}
} else if (Platform.isIOS) {
var status = await Permission.notification.isGranted;
if (!status) {
await Permission.notification.request();
}
}
}

@pragma('vm:entry-point')
void backgroundFetchHeadlessTask(HeadlessTask task) async {
print("Headless Task Triggered: ${task.taskId}");
try {
await BackGroundHelper().showNotification();
} catch (e) {
print("Error in headless task: $e");
}
BackgroundFetch.finish(task.taskId);
}

void initBackgroundFetch() {
print("initBackgroundFetch");
BackgroundFetch.configure(
BackgroundFetchConfig(
minimumFetchInterval: 15,
stopOnTerminate: false,
enableHeadless: true,
startOnBoot: true,
),
(String taskId) async {
print("[BackgroundFetch] Event received: $taskId");
await showNotification();
BackgroundFetch.finish(taskId);
},
).then((int status) {
print("[BackgroundFetch] configure success: $status");
}).catchError((e) {
print("[BackgroundFetch] configure ERROR: $e");
});
}

void startTimer() {
_timer = Timer.periodic(Duration(seconds: 15), (timer) {
showNotification();
});
}

void stopTimer() {
_timer.cancel();
}

void ini() {
BackgroundFetch.registerHeadlessTask(backgroundFetchHeadlessTask);
}
}

@christocracy
Copy link
Member

The issue template is required, not optional;

Your Environment

  • Plugin version:
  • Platform: iOS or Android
  • OS version:
  • Device manufacturer / model:
  • Flutter info (flutter info, flutter doctor):
  • Plugin config

To Reproduce
Steps to reproduce the behavior:
1.
2.
3.
4.

Debug logs

  • ios XCode logs,
  • Android: $ adb logcat

Additional context
Add any other context about the problem here.

@coskuncay
Copy link

hey @christocracy ,

When I trigger background fetch through Xcode, it works, but if I don't do that or leave my real device idle, it doesn't work at all. What can I do?

@christocracy
Copy link
Member

christocracy commented Oct 23, 2024

It can take days before the OS machine-learning model begins firing regular events. This issue has been posted hundreds of times over the last 10 years.

There is no way to control when the OS decides to fire events.

just periodically bring your app to the foreground throughout the day, to simulate regular user behaviour.

iOS will halt firing events if the user manually terminates the app.

if simulated events work, your job is done. Now you wait.

Copy link

This issue is stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the stale label Nov 23, 2024
Copy link

github-actions bot commented Dec 7, 2024

This issue was closed because it has been inactive for 14 days since being marked as stale.

@github-actions github-actions bot closed this as completed Dec 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants