【发布时间】:2022-09-27 16:22:52
【问题描述】:
我正在开发我的 Flutter 应用程序,并在创建实体(用户)后尝试设置重定向过程。状态管理由 Riverpod 处理。我将 Firebase 用于身份验证,将 Postgres 用于数据库。
存储库中的 insert 方法返回一个用户。使用StateNotifier 我只想检查该方法是否返回用户。如果返回用户,我设置一个成功状态对象 (CreateAccountStateSuccess),如果不是,我设置一个带有消息的错误状态对象。问题:我的saveUser 方法总是在我的StateNotifier 中返回null,即使我的用户保存在Firebase 和我的数据库中。我认为这是 Riverpod 的问题。任何想法?
我的存储库:
Future<AppUser?> saveUser(String email, String nickname, String role,
String firstname, String lastname) async {
try {
connection.open().then((value) async {
Future<List<Map<String, Map<String, dynamic>>>> result = connection.mappedResultsQuery(
\'insert into public.user(email,nickname,role,firstname,lastname) \'
\'values(@emailValue,@nicknameValue,@roleValue,@firstnameValue,@lastnameValue) \'
\'returning *\',
substitutionValues: {
\'emailValue\': email,
\'nicknameValue\': nickname,
\'roleValue\': role,
\'firstnameValue\': firstname,
\'lastnameValue\': lastname,
},
allowReuse: true,
timeoutInSeconds: 30,
);
result.then((value) {
final userFromDataBase = value[0][\'user\']!;
return AppUser(
email: userFromDataBase[\'email\'],
nickname: userFromDataBase[\'nickname\'],
role: userFromDataBase[\'role\'],
firstname: userFromDataBase[\'firstname\'],
lastname: userFromDataBase[\'lastname\']
);
});
});
} catch (e) {
print(ErrorHandler(message: e.toString()));
return null;
}
return null;
}
我的 Firebase 方法为 Firebase 创建用户并使用我的存储库方法:
Future<AppUser?> registerWithEmailAndPassword(String email, String password, String nickname, String role, String firstname, String lastname) async {
FirebaseApp app = await Firebase.initializeApp(
name: \'Secondary\', options: Firebase.app().options);
try {
UserCredential result =
await FirebaseAuth.instanceFor(app: app).createUserWithEmailAndPassword(email: email, password: password);
User? user = result.user;
if (user == null) {
throw Exception(\"No user found\");
} else {
try {
return await UserRepository(user.email!).saveUser(email, nickname, role, firstname, lastname);
} on PostgreSQLException catch (e) {
print(\'CATCH POSTGRES EXCEPTION\');
print(ErrorHandler(message: e.code.toString()));
}
}
} on FirebaseException catch (e) {
print(\'CATCH FIREBASE EXCEPTION\');
print(ErrorHandler(message: e.code.toString()));
}
return null;
}
我的控制器:
class CreateAccountController extends StateNotifier<CreateAccountState> {
CreateAccountController(this.ref) : super(const CreateAccountStateInitial());
final Ref ref;
void register(String email, String password, String nickname, String role, String firstname, String lastname) async {
state = const CreateAccountStateLoading();
try {
await ref.read(authRepositoryProvider).registerWithEmailAndPassword(
email,
password,
nickname,
role,
firstname,
lastname
).then((user){
user != null ? state = const CreateAccountStateSuccess() : state = const CreateAccountStateError(\'Something went wrong with the user creation in database\');
});
} catch (e) {
state = CreateAccountStateError(e.toString());
}
}
}
final createAccountControllerProvider =
StateNotifierProvider<CreateAccountController, CreateAccountState>((ref) {
return CreateAccountController(ref);
});
我的状态对象:
class CreateAccountState extends Equatable {
const CreateAccountState();
@override
List<Object> get props => [];
}
class CreateAccountStateInitial extends CreateAccountState {
const CreateAccountStateInitial();
@override
List<Object> get props => [];
}
class CreateAccountStateLoading extends CreateAccountState {
const CreateAccountStateLoading();
@override
List<Object> get props => [];
}
class CreateAccountStateSuccess extends CreateAccountState {
const CreateAccountStateSuccess();
@override
List<Object> get props => [];
}
class CreateAccountStateError extends CreateAccountState {
final String error;
const CreateAccountStateError(this.error);
@override
List<Object> get props => [error];
}
我的屏幕:
class CreateAccountScreen extends StatefulHookConsumerWidget {
const CreateAccountScreen({Key? key}) : super(key: key);
@override
ConsumerState<CreateAccountScreen> createState() => _CreateAccountScreenState();
}
class _CreateAccountScreenState extends ConsumerState<CreateAccountScreen> {
TextEditingController emailController = TextEditingController();
TextEditingController passwordController = TextEditingController();
TextEditingController nicknameController = TextEditingController();
TextEditingController roleController = TextEditingController();
TextEditingController firstnameController = TextEditingController();
TextEditingController lastnameController = TextEditingController();
@override
Widget build(BuildContext context) {
ref.listen<CreateAccountState>(createAccountControllerProvider, ((previous, state) {
if (state is CreateAccountStateError) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(state.error.toString()),
backgroundColor: Colors.red,
));
}
print(state.toString());
if (state is CreateAccountStateSuccess) {
context.goNamed(\'/\', params:
{
\'screenName\': \'users\'
});
}
}));
return Scaffold(
appBar: AppBar(
title: const Text(\'Create an account\'),
elevation: 8.0,
backgroundColor: Colors.deepOrangeAccent,
actions: [
TextButton.icon(
icon: const Icon(
Icons.logout_rounded,
color: Colors.white,
),
label: const Text(\'\', style: TextStyle(color: Colors.white)),
onPressed: () async {
ref.read(loginControllerProvider.notifier).signOut();
},
),
]
),
body: Padding(
padding: const EdgeInsets.all(10),
child: ListView(
children: <Widget>[
Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(10),
child: const Text(
\'Ludocal 2\',
style: TextStyle(
color: Colors.deepOrange,
fontWeight: FontWeight.w500,
fontSize: 30),
)),
Container(
padding: const EdgeInsets.all(10),
child: TextFormField(
validator: (value) =>
value == null || value.isEmpty ? \"Enter an email\" : null,
controller: emailController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: \'Email Address\',
),
),
),
Container(
padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
child: TextFormField(
obscureText: true,
validator: (value) =>
value == null || value.isEmpty ? \"Enter a password\" : null,
controller: passwordController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: \'Password\',
),
),
),
Container(
padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
child: TextFormField(
validator: (value) =>
value == null || value.isEmpty ? \"Enter a nickname\" : null,
controller: nicknameController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: \'Nickname\',
),
),
),
Container(
padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
child: TextFormField(
validator: (value) =>
value == null || value.isEmpty ? \"Enter a role\" : null,
controller: roleController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: \'Role\',
),
),
),
Container(
padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
child: TextFormField(
validator: (value) =>
value == null || value.isEmpty ? \"Enter a firstname\" : null,
controller: firstnameController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: \'Firstname\',
),
),
),
Container(
padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
child: TextFormField(
validator: (value) =>
value == null || value.isEmpty ? \"Enter a lastname\" : null,
controller: lastnameController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: \'Lastname\',
),
),
),
Container(
height: 50,
padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
margin: const EdgeInsets.only(top:20),
child: ElevatedButton(
child: const Text(\'Create\', style: TextStyle(color: Colors.white)),
onPressed: () {
ref
.read(createAccountControllerProvider.notifier)
.register(emailController.text, passwordController.text, nicknameController.text,
roleController.text, firstnameController.text, lastnameController.text);
},
)),
],
)),
);
}
}
标签: postgresql flutter firebase dart riverpod