首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >错误:权限丢失或权限不足

错误:权限丢失或权限不足
EN

Stack Overflow用户
提问于 2020-05-15 14:01:35
回答 1查看 145关注 0票数 0

我在我的应用程序中创建用户时遇到了麻烦,我收到一个错误,说我没有足够的权限,即使我应该有权限。我的安全规则允许创建用户,所以我真的不明白为什么我会收到这个错误。更奇怪的是,它在我的同事的电脑上工作,他可以创建用户(用完全相同的用户细节)。他在pc上,我在mac上,不确定这是否重要?

我得到的错误如下:[VERBOSE-2:ui_dart_state.cc(157)] Unhandled Exception: PlatformException(Error 7, FIRFirestoreErrorDomain, Missing or insufficient permissions.)

我们的安全规则是:

代码语言:javascript
复制
service cloud.firestore {
        //match /databases/{database}/documents {


  match /databases/{database}/documents {
    match /{document=**} {
        allow read: if request.auth != null;
    }

    match /Users/{userId} {
        allow update: if request.auth.uid == userId;
    }

    match /Users/{document=**} {
        allow create;
    }


    match /Recipes/{document=**} {
        allow create: if request.auth != null;
      allow update, delete: if request.resource.data.userId == request.auth.uid;
    }

    match /Recipes/{document=**}/newRatings {
    allow create, update: if request.auth != null;
    }

  }

} ```

Our code for registering users is:

´´´ import 'package:cibus/pages/loginScreens/username_screen.dart';
import 'package:cibus/pages/loginScreens/verify_screen.dart';
import 'package:cibus/services/colors.dart';
import 'package:flutter/material.dart';
import 'package:cibus/services/login/auth.dart';
import 'package:cibus/services/constants.dart';
import 'package:cibus/pages/loginScreens/e-sign_in_screen.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_user_stream/firebase_user_stream.dart';
import 'package:cibus/services/my_page_view.dart';
import 'package:provider/provider.dart';
import 'package:cibus/services/login/user.dart';
import 'package:cibus/services/database.dart';
import 'package:cibus/pages/loading_screen.dart';

const registerButtonColor = kTurquoise;
const formSizedBox = SizedBox(height: 20.0);
const EdgeInsets formPadding =
    EdgeInsets.symmetric(vertical: 10.0, horizontal: 50.0);
const TextStyle textStyleErrorMessage =
    TextStyle(color: Colors.red, fontSize: 14.0);
const TextStyle textStyleRegisterButton = TextStyle(color: Colors.white);

OutlineInputBorder textInputBorder = OutlineInputBorder(
  borderRadius: BorderRadius.circular(25.0),
);

class RegisterScreen extends StatefulWidget {
  final Function toggleView;
  RegisterScreen({this.toggleView});

  @override
  _RegisterScreenState createState() => _RegisterScreenState();
}

class _RegisterScreenState extends State<RegisterScreen> {
  final AuthService _auth = AuthService();
  final _formKey = GlobalKey<FormState>();
  bool loading = false;
  bool isVerified = false;
  //final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;

  //text field state
  String email = '';
  String password = '';
  String error = '';
  String name = '';
  String description = '';
  String _currentUsername;
  int age = 0;
  int dropdownValue = null;
  final TextEditingController _pass = TextEditingController();
  final TextEditingController _confirmPass = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return loading
        ? LoadingScreen()
        : Scaffold(
            backgroundColor: Theme.of(context).backgroundColor,
            appBar: AppBar(
              backgroundColor: Theme.of(context).backgroundColor,
              elevation: 0.0,
              title: Text('Sign up to Cibus', style: TextStyle(color: kCoral)),
              actions: <Widget>[
                FlatButton.icon(
                  icon: Icon(Icons.person, color: kCoral),
                  label: Text('Sign in', style: TextStyle(color: kCoral)),
                  onPressed: () {
                    //widget.toggleView();
                    Navigator.of(context).pushReplacement(
                      MaterialPageRoute(
                        builder: (context) {
                          return EmailSignIn();
                        },
                      ),
                    );
                  },
                ),
              ],
            ),
            body: Padding(
              padding: formPadding,
              child: SingleChildScrollView(
                child: Form(
                    key: _formKey,
                    child: Column(children: <Widget>[
                      formSizedBox,
                      TextFormField(
                        keyboardType: TextInputType.emailAddress,
                        decoration: InputDecoration(
                          enabledBorder: textInputBorder,
                          border: textInputBorder,
                          labelText: 'Email',
                        ),
                        validator: (val) =>
                            val.isEmpty ? 'Enter an email' : null,
                        onChanged: (val) {
                          setState(() => email = val);
                        },
                      ),
                      formSizedBox,
                      TextFormField(
                        decoration: InputDecoration(
                          enabledBorder: textInputBorder,
                          border: textInputBorder,
                          labelText: 'Password',
                        ),
                        obscureText: true,
                        controller: _pass,
                        validator: (String val) {
                          Pattern pattern =
                              r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!@#\$&*~]).{8,}$';
                          RegExp regex = new RegExp(pattern);
                          print(val);
                          if (val.isEmpty) {
                            return 'Please enter password';
                          } else if (val.length < 8) {
                            return 'Minimum 8 characters required';
                          } else if (!val.contains(RegExp(r'[A-Z]'))) {
                            return 'One upper case letter required.';
                          } else if (!val.contains(RegExp(r'[a-z]'))) {
                            return 'One lower case letter required.';
                          } else if (!val.contains(RegExp(r'[0-9]'))) {
                            return 'One digit required.';
                          } else if (!val
                              .contains(RegExp(r'[!@#$%^&*(),.?":{}|<>]'))) {
                            return 'One special character required.';
                          } /*

                          else {
                            if (!regex.hasMatch(val))
                              return 'Enter valid password: \n'
                                  'Password must contain at least one upper case letter. \n'
                                  'Password must contain at least one lower case letter. \n'
                                  'Password must contain at least one digit. \n'
                                  'Password must contain at least one special character.'; */
                          else
                            return null;
                          //}
                        },
                        onChanged: (val) {
                          setState(() => password = val);
                        },
                      ),
                      formSizedBox,
                      TextFormField(
                        decoration: InputDecoration(
                          enabledBorder: textInputBorder,
                          border: textInputBorder,
                          labelText: ' Re-enter Password',
                        ),
                        obscureText: true,
                        controller: _confirmPass,
                        validator: (String val) {
                          if (val.isEmpty)
                            return 'Re-enter password field is empty';
                          if (val != _pass.text)
                            return 'passwords do not match';
                          return null;
                        },
                        onChanged: (val) {
                          setState(() => password = val);
                        },
                      ),
                      formSizedBox,
                      TextFormField(
                        decoration: InputDecoration(
                          enabledBorder: textInputBorder,
                          border: textInputBorder,
                          labelText: 'Name',
                        ),
                        validator: (val) =>
                            val.isEmpty ? 'Enter your name' : null,
                        onChanged: (val) {
                          setState(() => name = val);
                        },
                      ),
                      formSizedBox,
                      TextFormField(
                        decoration: InputDecoration(
                          enabledBorder: textInputBorder,
                          border: textInputBorder,
                          labelText: 'Description',
                        ),
                        minLines: 5,
                        maxLines: 10,
                        validator: (val) =>
                            val.isEmpty ? 'Enter your description' : null,
                        onChanged: (val) {
                          setState(() => description = val);
                        },
                      ),
                      formSizedBox,
                      TextFormField(
                          maxLength: 20,
                          decoration: InputDecoration(
                            enabledBorder: textInputBorder,
                            border: textInputBorder,
                            labelText: 'Username',
                          ),
                          validator: (val) {
                            if (val.length < 3)
                              return 'Username must be more than 2 characters';
                            /*else if (checkUsername == false)
                          return 'Username is allready taken';*/
                            return null; 

                          },
                          onChanged: (val) {
                            setState(() {
                              _currentUsername = val;
                              print(_currentUsername);
                            });
                          }),
                      formSizedBox,
                      RaisedButton(
                        color: kCoral,
                        child: Text('Register', style: textStyleRegisterButton),
                        onPressed: () async {
                          if (_formKey.currentState.validate()) {
                            setState(() => loading = true);
                            bool isUsernameFree = await DatabaseService()
                                .isUsernameTaken(username: _currentUsername);
                            print(' checkUsername: $isUsernameFree');
                            if (!isUsernameFree) {
                              dynamic result =
                                  await _auth.registerWithEmailAndPassword(
                                      email, password, name, description, age);
                              if (result == null) {
                                setState(() {
                                  error = 'Email is already registered';
                                  _verificationEmailDialog();
                                });
                              } else {
                                Navigator.of(context).pushReplacement(
                                  MaterialPageRoute(
                                    builder: (context) {
                                      return VerifyScreen();
                                    },
                                  ),
                                );
                              }
                            } else {
                              setState(() {
                                error = 'Username is already taken';
                              });
                              _usernameDialog();
                            }
                          }
                        },
                      ),
                      Text(
                        error,
                        style: textStyleErrorMessage,
                      ),
                    ])),
              ),
            ));
  }

  Future<void> _usernameDialog() async {
    return showDialog<void>(
      context: context,
      barrierDismissible: false, // user must tap button!
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('Username is already taken'),
          content: SingleChildScrollView(
            child: ListBody(
              children: <Widget>[
                Text(
                    'Unfortunately it seems like your username is allready taken. Please try another one'),
              ],
            ),
          ),
          actions: <Widget>[
            FlatButton(
              child: Text('Aight bruh'),
              onPressed: () {
                setState(() {
                  loading = false;
                });
                Navigator.of(context)
                    .pop(); //TODO: When popping try to keep text in forms
              },
            ),
          ],
        );
      },
    );
  }

  Future<void> _verificationEmailDialog() async {
    return showDialog<void>(
      context: context,
      barrierDismissible: false, // user must tap button!
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('Email is already in use'),
          content: SingleChildScrollView(
            child: ListBody(
              children: <Widget>[
                Text(
                    'Unfortunately it seems like the email is already in use. Please try another one'),
              ],
            ),
          ),
          actions: <Widget>[
            FlatButton(
              child: Text('Aight bruh'),
              onPressed: () {
                setState(() {
                  loading = false;
                });
                Navigator.of(context)
                    .pop(); //TODO: When popping try to keep text in forms
              },
            ),
          ],
        );
      },
    );
  }
}


and here is the registerWithEmailAndPassword function:

 Future registerWithEmailAndPassword(String email, String password,
      String name, String description, int age) async {
    try {
      AuthResult result = await _auth.createUserWithEmailAndPassword(
          email: email, password: password);
      FirebaseUser user = result.user;

      user.sendEmailVerification();
      user.isEmailVerified;
      print('Email verification sent?');

      //create a new document for the user with the uid
      await DatabaseService(uid: user.uid)
          .updateUserData(name: name, description: description, age: age);
      await DatabaseService(uid: user.uid).updateUserPicture(
          pictureURL:
              'https://firebasestorage.googleapis.com/v0/b/independent-project-7edde.appspot.com/o/blank_profile_picture.png?alt=media&token=49efb712-d543-40ca-8e33-8c0fdb029ea5');
      return _userFromFirebaseUser(user);
    } catch (e) {
      print(e.toString());
      return null;
    }
  }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-18 08:49:05

这是我在安全规则上的一个错误。我认为用户可以创建用户,但是他们只能在经过身份验证的情况下才能读取,所以当我检查用户名是否被使用时,会发生错误,因为我没有读取权限。我刚在用户上添加了读取部分,它可以工作。

代码语言:javascript
复制
match /Users/{document=**} {
        allow create: if true;
      allow read: if true;
    } 
´´´
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61821108

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档