【发布时间】:2022-01-05 20:04:17
【问题描述】:
借助 stackoverflow 的帮助,我已经能够让 Firebase 身份验证适用于 Google 登录、匿名登录以及通过电子邮件和密码登录,包括在电子邮件和密码登录期间发送验证电子邮件。一切都按预期工作。现在我的下一步是尝试使用 Firebase 身份验证创建的 uid 在 Firestore 中创建一个用户集合。我确信我的代码编写正确,因为我已经使用(不安全的)安全规则对其进行了测试,并且该过程完全符合预期。 我已经多次查看 Firebase 文档,但我无法弄清楚我的安全规则代码有什么问题。如何修复我的安全规则以允许新用户创建将添加到 Firestore 中的用户集合的屏幕名称?在此先感谢您的帮助。
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{uid}/jobs/{document=**} {
allow read, write: if request.auth.uid == uid;
}
match /users/{uid}/{document=**} {
allow read, write: if request.auth.uid == uid;
}
}
}
class HomePage extends StatefulWidget {
const HomePage({
Key? key,
}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
void initState() {
super.initState();
createUserInFirestore();
}
Future<void> createUserInFirestore() async {
final GoogleSignIn googleSignIn = GoogleSignIn();
final GoogleSignInAccount? user = googleSignIn.currentUser;
final usersRef = FirebaseFirestore.instance.collection('users');
final DocumentSnapshot doc = await usersRef.doc(user?.id).get();
if (!doc.exists) {
final userName = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const CreateAccountPage(),
),
);
usersRef.doc(user?.id).set({
'id': user?.id,
'userName': userName,
'photoUrl': user?.photoUrl,
'email': user?.email,
'displayName': user?.displayName,
'bio': '',
'timestamp': documentIdFromCurrentDate(),
});
doc = await usersRef.doc(user?.id).get();
}
}
@override
Widget build(BuildContext context) {
return AdaptiveLayoutScaffold(
drawer: const SideSheet(
userImage: FakeUserAvatars.stacy,
userName: 'Stacy James',
),
landscapeBodyWidget: Container(),
portraitBodyWidget: Container(),
);
}
}
class CreateAccountPage extends StatefulWidget {
const CreateAccountPage({
Key? key,
}) : super(key: key);
@override
_CreateAccountPageState createState() => _CreateAccountPageState();
}
class _CreateAccountPageState extends State<CreateAccountPage> {
final _formKey = GlobalKey<FormState>();
late String userName;
void submit() {
_formKey.currentState?.save();
Navigator.pop(context, userName);
}
@override
Widget build(BuildContext context) {
return AdaptiveLayoutScaffold(
appBar: const Header(
automaticallyImplyLeading: false,
pageName: 'User Name',
),
landscapeBodyWidget: Container(),
portraitBodyWidget: ListView(
children: [
Column(
children: [
const Padding(
padding: EdgeInsets.only(top: 16.0),
child: Center(
child: Text('Create a User Name'),
),
),
Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: TextFormField(
autovalidateMode: AutovalidateMode.always,
decoration: InputDecoration(
hintText: 'Must be between 3 and 20 characters',
labelText: 'User Name',
prefixIcon: Icon(
Icons.person,
color: Theme.of(context).iconTheme.color,
),
),
keyboardType: TextInputType.text,
onSaved: (val) => userName = val as String,
),
),
),
PlatformElevatedButton(
onPressed: submit,
buttonText: 'Create User Name',
),
],
),
],
),
);
}
}
【问题讨论】:
-
当您通过命名任何集合添加数据时,Firestore 会自动创建集合。您是否收到任何权限错误?
-
正在 Firebase 中创建新用户,但控制台显示“失败:状态{code=PERMISSION_DENIED, description=Missing 或权限不足。, cause=null。未处理的异常:[cloud_firestore/permission-denied] 调用者没有执行指定操作的权限。 @Anuj Raghuvanshi
-
是的,没错。这是您为安全规则添加的内容。登录后允许访问该集合。但如果没有登录,您将无法访问任何集合进行操作。您可以添加
match /users/{uid}/users/{document=**} { allow read, write: if true; }让用户收藏始终可读可写并尝试这样做。 -
添加为我拥有的规则的替代品或添加的规则? @AnujRaghuvanshi。我尝试了两种方式(我认为)并且出现了同样的错误,这很奇怪。新用户是在 Firebase 中创建的,但在 Firestore 中没有创建任何集合,应用会直接进入主页而不是创建帐户页面。
-
@CarletonY,你能检查一下这个thread,看看它是否有帮助。谢谢。
标签: firebase flutter google-cloud-firestore firebase-security