Reputation: 661
I want to make a class and put similar methods together.
Riverpod works using ref which is only available through extending but how to use it in bare class which doesn't have any extends and build methods.
Model
class User {
final String uid;
final String username;
final String email;
User({required this.uid, required this.username, required this.email});}
StateNotifier
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../models/user.dart';
class UserProvider extends StateNotifier<User> {
UserProvider()
: super(User(
email: '',
username: 'default',
uid: '',
));
addUser(User user) {
state = user;
}}
Place of use / a class
import 'package:cloud_firestore/cloud_firestore.dart';
import '../providers/user_provider.dart';
import '../models/user.dart' as model;
class FirestoreMethods {
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
// HOW TO USE RIVERPOD HERE IN PLACE OF PROVIDER.
// EXAMPLE OF PROVIDER-
// final user = Provider.of<UserProvider>(context, listen: false);
// print(user.email);
// print(user.uid);
// print(user.username);
// Example of Riverpod
// final userProvider = StateNotifierProvider<UserProvider,
// model.User>((ref) => UserProvider());
// ABOVE RIVERPOD DOES NOT WORK HERE
}
Upvotes: 2
Views: 6317
Reputation: 6127
Here is the general-purpose solution.
Create RefHolder which obtains Ref
reference from DummyProvider
. I called it Dummy koz it does not really provides anything.
class DummyNotifier extends Notifier<bool> {
@override
bool build() {
refHolder = RefHolder._(ref);
return true;
}
}
final dummyProvider = NotifierProvider<DummyNotifier, bool>(() {
return DummyNotifier();
});
late RefHolder refHolder;
class RefHolder {
final Ref _ref;
RefHolder._(this._ref);
get ref {
return _ref;
}
}
Read the provider from the MainApp build method to ensure the RefHolder singleton is created.
Widget build(BuildContext context, WidgetRef ref) {
ref.read(dummyProvider);
Use from anywhere. For example, from the local notifications method:
Future _showNotificationWithDefaultSound(notifPlugin) async {
Ref ref = refHolder.ref;
//use ref to get required info from providers
Upvotes: 3
Reputation: 4134
@AnmolSingh While creating StateNotifierProvider you can directly pass User model class. I have modified your code. If you tap the fab button it will update userProvider provider state and it will refresh the UI. You can run this code in dartpad itself.
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(ProviderScope(child: MyApp()));
}
class MyApp extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final user = ref.watch(userProvider);
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: darkBlue,
),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: Text("UserName: ${user.username}"),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
ref.read(userProvider.notifier).addUser(User(
email: "[email protected]",
uid: "1",
username: "MSARKrish",
));
},
),
));
}
}
class User {
final String uid;
final String username;
final String email;
User({required this.uid, required this.username, required this.email});
}
class UserProvider extends StateNotifier<User> {
UserProvider()
: super(User(
email: '',
username: 'default',
uid: '',
));
addUser(User user) {
state = user;
}
}
final userProvider =
StateNotifierProvider<UserProvider, User>((ref) => UserProvider());
You can pass ref as parameter for any class
class FirestoreMethods
{
FirestoreMethods(this.ref)
final Ref ref;
}
Upvotes: 3