When trying to read a collection from cloud_firestore
, I’m using riverpod provider.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import '../dataStructs.dart';
part 'ChargesProvider.g.dart';
@riverpod
class GetCharges extends _$GetCharges {
@override
Future<Charges> build({required Layers layer}) async {
final layerNumber = layer.toDBName();
final layerDoc = 'Layers-$layerNumber';
final chargeSnapshot =
await FirebaseFirestore.instance.collection('charge').doc(layerDoc).get();
final chargeMap = chargeSnapshot.data()!;
return Charges.fromMap(chargeMap);
}
}
The code inside above build function works, tested by writing it directly in onPressed of a button. So it gets the data without any errors.
But when called like below in onPressed of a button using ref.read the provider immediately disposes.
Align(
alignment: Alignment.centerRight,
child: CustomOutlinedButton(
text: 'Continue',
onPressed: () {
if (chosenProduct != null) {
Charges charges;
ref.read(GetChargesProvider(layer: chosenProduct.layers))
.when(data: (chrg) {
charges = chrg;
print(charges);
return AsyncValue.data(chrg);
}, error: (err, stTrc) {
print('ERROR: $err');
return AsyncValue.data(defaultValue);
}, loading: () {
print('isLOADING');
return AsyncValue.data(defaultValue);
});
}
},
),
),
Below is the output on terminal.
Provider getChargesProvider:GetChargesProvider#53198(null) was initialized with AsyncLoading<Charges>()
isLOADING
Provider getChargesProvider:GetChargesProvider#53198(null) was disposed
I have tried saving my ref.read statement in a variable and then use it but got same results, it disposes. I am not using this provider anywhere else. Please suggest how to use the value of this provider. I’m using riverpod here because in case on the same page if this provider is required again, then it does not re-pull the data from firestore.
2
Answers
Below solution works for me but better solutions are welcome.
ref.read as per docs read the current state of the provider. So, directly reading a new provider (not watched before/having no state) in a onPressed function was causing it to dispose the provider (correct me if I'm wrong). I changed my function to -
Above function works on single click of button, i.e. waits for provider to return the value and perform required operations post that. Also provider is updated as below -
Also, used below directly from riverpod docs
To prevent auto dispose, call
ref.keepAlive();
inProvider.build
Or set
keepAlive
to true in riverpod annotation.