I'd like to add more info the following UserModel and make it available throughout all screens of the app. I've been struggling with the basics of Provider. Should I use a separate class extending the ChangeNotifier and store those additional properties there? The example below is trying to add idVendor (id_vendor). I could use ProviderOf on every place where I need that information but it would be a new request every time I do it. Any help would be really appreciated:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:firebase_core/firebase_core.dart';
import 'dart:convert';
import 'package:firebase_auth/firebase_auth.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(const App());
}
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
Provider<AuthRepository>(create: (_) => AuthRepository()),
StreamProvider<UserModel?>(create: (context) =>
context.read<AuthRepository>().monitorAuthStateChanges,
initialData: null,
),
],
child: const MaterialApp(home: AuthCheck()),
);
}
}
class AuthCheck extends StatelessWidget {
const AuthCheck({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final userModel = Provider.of<UserModel?>(context);
if (userModel != null) {
return const MainPage();
} else {
return const LoginScreen();
}
}
}
class UserModel {
final String uid;
late final int? idVendor;
UserModel({required this.uid, this.idVendor});
}
class AuthRepository {
final FirebaseAuth _fireAuth = FirebaseAuth.instance;
Stream<UserModel?> get monitorAuthStateChanges {
return _fireAuth.authStateChanges().map(_userModel);
}
UserModel? _userModel(User? user) {
if (user != null) {
return UserModel(uid: user.uid);
} else {
return null;
}
}
Future<void> addInfoToUser() async {
final userModel = _userModel(_fireAuth.currentUser);
if (userModel != null) {
String endPoint = '${ApiEndPoints.userIdVendor}';
String url = endPoint.replaceAll('id', userModel.uid);
try {
final response = await http.get(Uri.parse(url), headers: {
'Content-Type': 'application/json; charset=utf-8',
}).timeout(const Duration(seconds: 60));
if (response.statusCode == 200) {
final Map<String, dynamic> jsonResponseBody =
jsonDecode(response.body);
final List<dynamic> data = jsonResponseBody['data'];
userModel.idVendor = data[0]['id_vendor'];
}
} on Exception catch (e) {
return Future.error('Exception\n($e)\n(${e.toString()})');
}
}
}
}
You can have
copyWith
method insideUserModel
to assign or changeidVendor
parameter.Then inside addInfo use
_userModel.copywith(idVendor: newId);