_AssertionError 'package:provider/src/provider.dart':断言失败:第 260 行 pos 12:'context != null':不是真的

时间:2021-02-14 15:20:22

标签: flutter provider

如果我仅使用提供程序设置一些值以通知侦听器(在 _validateAndSubmit 方法中),则会发生此错误。我想将用户名和图像链接存储在内存中,而不是每次都从 firestore 中获取数据。我正在使用有状态小部件,据我所知,上下文随处可用,并且弹出的对话框工作正常。我真的不明白是什么导致了异常。请帮我解决问题。 enter image description here

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:form_builder_image_picker/form_builder_image_picker.dart';
import 'package:path/path.dart'
    as path; // provides common operations for manipulating paths: joining, splitting, normalizing
import '../providers/user_settings.dart';

class AuthScreen extends StatefulWidget {
  @override
  _AuthScreenState createState() => _AuthScreenState();
}

class _AuthScreenState extends State<AuthScreen> {
  File _pickedImage;
  final _initialValues = {
    'username': '',
    'email': '',
    'password': '',
  };
  var _isLogin = true;
  final _formKey = GlobalKey<FormBuilderState>();
  final _auth = FirebaseAuth.instance;
  var _isLoading = false;
  Future<void> _validateAndSubmit() async {
    bool valid = _formKey.currentState.validate();
    FocusScope.of(context).unfocus(); // close soft keyboard after submiting
    if (!valid) {
      return;
    }

    _formKey.currentState.save();
    // used below to get user id and to signIn or register user
    AuthResult result;

    try {
      setState(() {
        _isLoading = true;
      });
      if (_isLogin) {
        result = await _auth.signInWithEmailAndPassword(
            email: _initialValues['email'],
            password: _initialValues['password']);
        final userId = result.user.uid;

        final userDetails =
            await Firestore.instance.collection('users').document(userId).get();

        Provider.of<UserSettings>(context, listen: false)
            .setUserInfo(userDetails['username'], userDetails['image']);
      } else {
        result = await _auth.createUserWithEmailAndPassword(
            email: _initialValues['email'],
            password: _initialValues['password']);

        final fileName = path.basename(_pickedImage.path);
        //print('image: ' + _pickedImage.uri.path);
        //final _authResult = await _auth.currentUser();
        // we used on complete to make it return future and use await
        final ref = FirebaseStorage.instance
            .ref()
            .child('avatars')
            .child(result.user.uid + fileName);
        await ref.putFile(_pickedImage).onComplete;

        final String imageUrl = await ref.getDownloadURL();

        await Firestore.instance
            .collection('users')
            .document(result.user.uid)
            .setData({
          'username': _initialValues['username'],
          'email': _initialValues['email'],
          'image': imageUrl,
        });

        context
            .read<UserSettings>()
            .setUserInfo(_initialValues['username'], imageUrl);
        //if (this.mounted) {
        setState(() {
          _isLoading = false;
        });
        //}
      }
    } on PlatformException catch (error) {
      var msg = 'An Error Occurred, Please Check Your Credentials';
      if (error.message != null) {
        msg = error.message;
        showDialog(
            context: context,
            builder: (context) => AlertDialog(
                  title: Text('Error'),
                  content: Text(msg),
                  actions: [
                    RaisedButton(
                      onPressed: () {
                        Navigator.of(context).pop();
                      },
                      child: Text('Ok'),
                    )
                  ],
                ));
        setState(() {
          _isLoading = false;
        });
      }
    } catch (error) {
      throw error;
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Theme.of(context).primaryColor,
      body: Center(
        child: Card(
          margin: EdgeInsets.all(20),
          child: SingleChildScrollView(
              child: Padding(
            padding: EdgeInsets.all(10),
            child: FormBuilder(
                key: _formKey,
                autovalidateMode: AutovalidateMode.onUserInteraction,
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    if (!_isLogin)
                      FormBuilderTextField(
                        key: ValueKey('username'),
                        name: 'username',
                        keyboardType: TextInputType.name,
                        decoration: InputDecoration(
                          labelText: 'Username',
                        ),
                        validator: FormBuilderValidators.compose([
                          FormBuilderValidators.required(context,
                              errorText: 'Please enter a username'),
                          FormBuilderValidators.minLength(context, 5,
                              errorText: 'Minimum five characters'),
                        ]),
                        onSaved: (value) {
                          _initialValues['username'] = value.trim();
                        },
                        onChanged: (value) {},
                      ),
                    FormBuilderTextField(
                      key: ValueKey('email'),
                      name: 'email',
                      keyboardType: TextInputType.emailAddress,
                      decoration: InputDecoration(
                        labelText: 'Email',
                      ),
                      validator: FormBuilderValidators.compose([
                        FormBuilderValidators.required(context,
                            errorText: 'Please enter an email'),
                        FormBuilderValidators.email(context,
                            errorText: 'Please enter a valid email'),
                      ]),
                      onSaved: (value) {
                        _initialValues['email'] = value.trim();
                      },
                      onChanged: (value) {
                        //print(value);
                      },
                    ),
                    FormBuilderTextField(
                      key: ValueKey('password'),
                      name: 'password',
                      decoration: InputDecoration(
                        labelText: 'Password',
                      ),
                      obscureText: true,
                      validator: FormBuilderValidators.compose([
                        FormBuilderValidators.required(context,
                            errorText: 'Please enter your password'),
                        FormBuilderValidators.minLength(context, 8,
                            errorText: 'Minimum 8 characters'),
                      ]),
                      onSaved: (value) {
                        _initialValues['password'] = value.trim();
                      },
                      onChanged: (value) {
                        _initialValues['password'] = value.trim();
                      },
                    ),
                    if (!_isLogin)
                      FormBuilderTextField(
                        key: ValueKey('repeat'),
                        name: 'repeat',
                        decoration: InputDecoration(
                          labelText: 'Repeat Password',
                        ),
                        obscureText: true,
                        validator: FormBuilderValidators.compose([
                          FormBuilderValidators.required(context,
                              errorText: 'Please repeat your password'),
                          FormBuilderValidators.minLength(context, 8,
                              errorText: 'Minimum 8 characters'),
                          (value) {
                            if (value != _initialValues['password']) {
                              return "Not equal";
                            }
                            return null;
                          },
                        ]),
                      ),
                    SizedBox(
                      height: 12,
                    ),
                    if (!_isLogin)
                      FormBuilderImagePicker(
                        name: 'image',
                        //previewWidth: MediaQuery.of(context).size.width * 0.83,
                        //previewHeight: 220,
                        maxWidth: 200,
                        onChanged: (value) {
                          if (value.isNotEmpty) {
                            _pickedImage = value[0];
                            print(_pickedImage);
                          }
                        },
                        onSaved: (value) {
                          _pickedImage = value[0];
                        },
                        //initialValue: _initialValues['image'],
                        imageQuality: 70,
                        //valueTransformer: (value) {},
                        validator: FormBuilderValidators.compose([
                          FormBuilderValidators.required(context,
                              errorText: 'Please select a photo'),
                        ]),
                        decoration:
                            const InputDecoration(labelText: 'Pick Image'),
                        maxImages: 1,
                      ),
                    if (_isLoading) CircularProgressIndicator(),
                    if (!_isLoading)
                      RaisedButton(
                        onPressed: _validateAndSubmit,
                        child: _isLogin ? Text('Login') : Text('SignUp'),
                      ),
                    if (_isLoading) CircularProgressIndicator(),
                    if (!_isLoading)
                      FlatButton(
                          onPressed: () {
                            setState(() {
                              _isLogin = !_isLogin;
                            });
                          },
                          child:
                              Text(_isLogin ? 'Create a new account' : 'Login'))
                  ],
                )),
          )),
        ),
      ),
    );
  }
}

0 个答案:

没有答案