使用 Riverpod 处理身份验证

Handle authentication with Riverpod

我正在尝试联系 Riverpod,但遇到了一些问题。

我创建了一个用于登录用户的表单,我试图在用户登录时更改主视图。 我的问题是,当我设置更改状态并导航回应用程序根目录时,新状态似乎不可用。但是,如果我保存文件或热重新加载应用程序,则新状态可用。

我做错了什么?

我的main.dart文件

import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:practical_riverpod/features/authenticated/authentication_state.dart';

import 'package:practical_riverpod/features/signup/signup_screen.dart';

void main() {
  runApp(ProviderScope(child: MyApp()));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends ConsumerWidget {
  @override
  Widget build(BuildContext context, ScopedReader watch) {
    final auth = watch(authProvider).state;

    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            Text(auth == null ? "not connected" : auth.firstname),
            RaisedButton(
              child: Text("gooooo"),
              onPressed: () {
                Navigator.of(context).push(
                  MaterialPageRoute(
                    builder: (context) => SignupScreen(),
                  ),
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

我有一个包含状态通知程序的文件:

import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:practical_riverpod/features/models/user_model.dart';

final authProvider = StateNotifierProvider((ref) {
  return AuthNotifier(null);
});

class AuthNotifier extends StateNotifier<UserModel> {
  AuthNotifier(UserModel state) : super(state);

  setCurrentUser(UserModel user) {
    state = user;
  }

  void clearUser() {
    state = null;
  }
}

注册屏幕

import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:practical_riverpod/features/authenticated/authentication_state.dart';
import 'package:practical_riverpod/features/models/user_model.dart';

class SignupScreen extends HookWidget {
  @override
  Widget build(BuildContext context) {
    final _firstnameController =
        useTextEditingController.fromValue(TextEditingValue.empty);

    final _lastname =
        useTextEditingController.fromValue(TextEditingValue.empty);
    final GlobalKey<FormState> _key = GlobalKey<FormState>();

    final auth = context.read(authProvider);

    return Scaffold(
      body: Column(
        children: [
          SizedBox(
            height: 190,
          ),
          Container(
            padding: EdgeInsets.all(20),
            child: Column(
              children: [
                Text("Signup"),
                Form(
                  key: _key,
                  child: Column(
                    children: [
                      TextFormField(
                        decoration: InputDecoration(hintText: "Your email"),
                        controller: _firstnameController,
                        validator: (value) => _firstnameController.text.isEmpty
                            ? "Can't be empty"
                            : null,
                      ),
                      TextFormField(
                        obscureText: true,
                        onSaved: (newValue) => print(newValue),
                        validator: (value) =>
                            _lastname.text.isEmpty ? "Can't be empty" : null,
                        decoration: InputDecoration(
                          hintText: "Password",
                        ),
                        controller: _lastname,
                      ),
                      RaisedButton(
                        child: Text("Create"),
                        onPressed: () {
                          if (_key.currentState.validate()) {
                            auth.setCurrentUser(
                              UserModel(
                                  firstname: _firstnameController.text,
                                  lastname: "_password.text"),
                            );
                            Navigator.of(context).pop();
                          }
                        },
                      )
                    ],
                  ),
                )
              ],
            ),
          )
        ],
      ),
    );
  }
}

最后是我的用户模型:

class UserModel {
  final String firstname;
  final String lastname;

  UserModel({this.firstname, this.lastname});
}

[Riverpod >= 0.14.0] 更改:

final auth = watch(authProvider).state;

至:

final auth = watch(authProvider);

[Riverpod < 0.14.0] 更改:

final auth = watch(authProvider).state;

至:

final auth = watch(authProvider.state);

我会向您的 Riverpod ProviderScope 推荐 adding a logger - 它在调试此类问题时真的很有帮助!