🙌

[Flutter] Riverpodのproviderに後で値を入れる方法

2023/01/16に公開

Riverpodのproviderにfirebase_authのUserCredential型の値を入れようと思ったときに、どうすればいいのか少し悩んだのでどうすればいいのか書いておきます。

間違った例

final credentialStateProvider = StateProvider<UserCredential>((ref) => null);

このままだとnullの部分にエラーが出て、
The return type 'Null' isn't a 'UserCredential', as required by the closure's context.
って言われます。
nullはUserCredential型では無いからだめだよってことですね。当然ですね

解決方法

下のようなコードにすれば解決します。

final credentialStateProvider = StateProvider<UserCredential?>((ref) => null);

型の宣言時に「?」をつけてnull許容にするだけです。簡単に解決できます。
providerにどうすれば後で値を入れることができるのかなと、検索しても出てこないのも納得です。すごく単純な解決方法なので、、、

追加:null型を格納する、意味のないprovider

下みたいに

final credentialStateProvider = StateProvider((ref) => null);

型の宣言を無くすと、エラーこそ出ませんが、後で値を代入しようとしたときに、エラーが出ます。なぜなら、null型しか代入できないproviderになっているからです。これは全く意味がありません

最適?だと思う書き方

ちなみにUserCredential型の値は簡単に変更はしたく無いので、きっと下のようなコードにしてStateProviderではなくProviderから値を読み取るようにしたほうがいいです。

final credentialStateProvider = StateProvider<UserCredential?>((ref) => null);
final credentialProvider = Provider((ref) => ref.watch(credentialStateProvider));

※(訂正)2行目がref.readになってましたが、ref.watchが正しいです。
ref.watchにしないとStateProviderの変更をProviderが監視して、適用することができないです。

 ref.watch(credentialStateProvider.notifier).state =
                    userCredential;
                print(ref.read(credentialProvider)?.credential);

格納値を変更できるStateProviderから値を保存し、
格納値が不変なProviderから値を読み取る。
こうすることで、UserCredentialを間違って書き換えるようなことは起こりません。

Discussion