Read provider inside a global or static method in Flutter

1k Views Asked by At

I have a question, regarding reading providers from inside static methods or global methods. I am using riverpod and awesome_notification packages, and I need to alter the state the app, from the action of the notification, for this, the package uses static methods inside a controller class.

class NotificationController{
  ...
  static Future<void> onActionReceivedMethod(ReceivedAction receivedAction) async {
    ...//some way to access a provider, to call methods on it
  }
  ...
}

If there is another way of doing this that I am not seeing, please let me know.

I have not been able to find a way to do this.

1

There are 1 best solutions below

3
On

You can:

  1. Pass to the ref function as a parameter.
static Future<void> onActionReceivedMethod(ReceivedAction receivedAction, Ref ref) async {
    final some = ref.read(someProvider);
  }
  1. Create a class that accepts the ref field in the constructor.

final notificationProvider = Provider((ref) => NotificationController(ref));

// or use tear-off
final notificationProvider = Provider(NotificationController.new);

class NotificationController {
  NotificationController(Ref ref) {
    _ref = ref;
  }

  static late final Ref _ref;

  static Future<void> onActionReceivedMethod(ReceivedAction receivedAction) async {
    final some = _ref.read(someProvider);
  }
}

An additional example:

import 'package:riverpod/riverpod.dart';

final valueProvider = Provider<int>((_) => 5);

final managerProvider = Provider(ManagerProvider.new);

class ManagerProvider {
  ManagerProvider(Ref ref) {
    _ref = ref;
  }

  static late final Ref _ref;

  static int getValue()  => _ref.read(valueProvider);

}

void main() {
  final container = ProviderContainer();

  container.read(managerProvider);
  
  final value = ManagerProvider.getValue();

  print(value); // 5
  
}

Either way, you should always have access to `Ref'.

Update:

As @OppositeDragon and @Eran Ravid pointed out, we really can't access _ref in a static method. However, if you define _ref in the constructor, it is possible. I think it's a terrible anti-pattern, though. Use method 1 and you will be fine.