繁体   English   中英

将数据插入 Cloud Firestore Flutter 时出错?

[英]Error while Inserting data into cloud firestore flutter?

我在管理页面上工作 我在特定页面中有三个字段,在我的插入工作正常之前,我在文本字段中显示错误消息时遇到了问题,但是当我修复该错误并开始运行我的应用程序时,我遇到了一个新的问题错误。有人可以帮助我吗。

这是我的代码:

class _AddPromoState extends State<AddPromo> {
  final databaseReference = Firestore.instance;

  var priceReductionController = TextEditingController();
  var perReductionController = TextEditingController();
  var promocodeController = TextEditingController();

  bool _validate = false;
  bool _validatePrice = false;
  bool _validatePerReduction = false;
  bool _validatePromoCode = false;


  @override
  void dispose() {
    priceReductionController.dispose();
    perReductionController.dispose();
    promocodeController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Add promo"),backgroundColor: Colors.indigo,),
      body: Column(
        children : <Widget>[
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: TextField(
              keyboardType: TextInputType.number,
            controller: priceReductionController,
              decoration: InputDecoration(labelText: "Price Reduction",
                  errorText: _validatePrice ? 'value cant be empty' : null,
                  border: new OutlineInputBorder(
                borderRadius: const BorderRadius.all(
                  const Radius.circular(0.0),
                ),
                borderSide: new BorderSide(
                  color: Colors.indigo,
                  width: 1.0,
                ),
              )),
            ),
          ),
         Padding(
           padding: const EdgeInsets.all(8.0),
           child: TextField(
             keyboardType: TextInputType.number,


             controller: perReductionController,
             decoration: new InputDecoration(labelText: "Percentage Reduction",
                 errorText: _validatePerReduction ? 'value cant be empty' : null,
                 border: new  OutlineInputBorder(
               borderSide: new BorderSide(color: Colors.indigo)

             )),


            ),
         ),
         Padding(
           padding: const EdgeInsets.all(8.0),
           child: TextField(

             controller: promocodeController,
             decoration: InputDecoration(labelText: "Promo code",
                 errorText: _validatePromoCode ? 'value cant be empty' : null,
                 border: OutlineInputBorder(

             )),

            ),
         ),
          Spacer(flex:2),
        Container(
          width: 350,

          child: RaisedButton(
            color: Colors.indigo,
            onPressed: () async {

              //perform the validation first
              setState(() {
                priceReductionController.text.isEmpty
                    ? _validatePrice = true
                    : _validatePrice = false;
                perReductionController.text.isEmpty
                    ? _validatePerReduction = true
                    : _validatePerReduction = false;
                promocodeController.text.isEmpty
                    ? _validatePromoCode = true
                    : _validatePromoCode = false;
              });

              //verify that all are fine
              if (_validatePrice || _validatePromoCode || _validatePerReduction) {
                return;
              }

              //store the values into the database
              DocumentReference ref = await databaseReference.collection("promo_codes")
                  .add({
                'percentage_reduction': perReductionController.text,
                'price_reduction': priceReductionController.text,
                'promo_code': promocodeController.text,
              });

              Scaffold.of(context)
                  .showSnackBar(SnackBar(content: Text("Promo saved.")))
                  .closed
                  .then((reason) {
                // snackbar is now closed
              });

              //print(ref.documentID);
            }, child: Text("Add Promo", style: TextStyle(color:Colors.white),)
        ) ]
      ),
    );
  }
}

我的错误消息如下所示:

E/flutter (13616): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception: Scaffold.of() called with a context that does not contain a Scaffold.
E/flutter (13616): No Scaffold ancestor could be found starting from the context that was passed to Scaffold.of(). This usually happens when the context provided is from the same StatefulWidget as that whose build function actually creates the Scaffold widget being sought.
E/flutter (13616): There are several ways to avoid this problem. The simplest is to use a Builder to get a context that is "under" the Scaffold. For an example of this, please see the documentation for Scaffold.of():
E/flutter (13616):   https://api.flutter.dev/flutter/material/Scaffold/of.html
E/flutter (13616): A more efficient solution is to split your build function into several widgets. This introduces a new context from which you can obtain the Scaffold. In this solution, you would have an outer widget that creates the Scaffold populated by instances of your new inner widgets, and then in these inner widgets you would use Scaffold.of().
E/flutter (13616): A less elegant but more expedient solution is assign a GlobalKey to the Scaffold, then use the key.currentState property to obtain the ScaffoldState rather than using the Scaffold.of() function.
E/flutter (13616): The context used was:
E/flutter (13616):   AddPromo
E/flutter (13616): #0      Scaffold.of (package:flutter/src/material/scaffold.dart:1316:5)
E/flutter (13616): #1      _AddPromoState.build.<anonymous closure> (package:adminbookingpage/screens/addPromo.dart:119:24)
E/flutter (13616): <asynchronous suspension>
E/flutter (13616): #2      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:706:14)
E/flutter (13616): #3      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:789:36)
E/flutter (13616): #4      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
E/flutter (13616): #5      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:486:11)
E/flutter (13616): #6      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:264:5)
E/flutter (13616): #7      BaseTapGestureRecognizer.handlePrimaryPointer (package:flutter/src/gestures/tap.dart:199:7)
E/flutter (13616): #8      PrimaryPointerGestureRecognizer.handleEvent (package:flutter/src/gestures/recognizer.dart:467:9)
E/flutter (13616): #9      PointerRouter._dispatch (package:flutter/src/gestures/pointer_router.dart:76:12)
E/flutter (13616): #10     PointerRouter._dispatchEventToRoutes.<anonymous closure> (package:flutter/src/gestures/pointer_router.dart:117:9)
E/flutter (13616): #11     _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:379:8)
E/flutter (13616): #12     PointerRouter._dispatchEventToRoutes (package:flutter/src/gestures/pointer_router.dart:115:18)
E/flutter (13616): #13     PointerRouter.route (package:flutter/src/gestures/pointer_router.dart:101:7)
E/flutter (13616): #14     GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:218:19)
E/flutter (13616): #15     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:198:22)
E/flutter (13616): #16     GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:156:7)
E/flutter (13616): #17     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:102:7)
E/flutter (13616): #18     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:86:7)
E/flutter (13616): #19     _rootRunUnary (dart:async/zone.dart:1138:13)
E/flutter (13616): #20     _CustomZone.runUnary (dart:async/zone.dart:1031:19)
E/flutter (13616): #21     _CustomZone.runUnaryGuarded (dart:async/zone.dart:933:7)
E/flutter (13616): #22     _invoke1 (dart:ui/hooks.dart:273:10)
E/flutter (13616): #23     _dispatchPointerDataPacket (dart:ui/hooks.dart:182:5)

在此处输入图片说明

从你的错误日志

E/flutter (13616):从传递给 Scaffold.of() 的上下文开始,找不到任何 Scaffold 祖先。 这通常发生在所提供的上下文来自与其构建函数实际创建正在寻找的 Scaffold 小部件相同的 StatefulWidget 时。 E/flutter (13616):有几种方法可以避免这个问题。 最简单的方法是使用 Builder 来获取 Scaffold “下”的上下文。 有关此示例,请参阅 Scaffold.of() 的文档:E/flutter (13616): https ://api.flutter.dev/flutter/material/Scaffold/of.html E/flutter (13616):更有效的解决方案是将您的构建功能拆分为多个小部件。 这引入了一个新的上下文,您可以从中获取 Scaffold。 在此解决方案中,您将拥有一个外部小部件,用于创建由新内部小部件的实例填充的 Scaffold,然后在这些内部小部件中您将使用 Scaffold.of()。 E/flutter (13616):一个不太优雅但更方便的解决方案是为 Scaffold 分配一个 GlobalKey,然后使用 key.currentState 属性获取 ScaffoldState 而不是使用 Scaffold.of() 函数。 E/flutter (13616): 使用的上下文是: E/flutter (13616): AddPromo E/flutter (13616): #0 Scaffold.of (package:flutter/src/material/scaffold.dart:1316:5) E /flutter (13616): #1 _AddPromoState.build。 (包:adminbookingpage/screens/addPromo.dart:119:24) E/flutter (13616):

如果您按照提供的链接操作您将看到当在同一个构建函数中实际创建 Scaffold 时,构建函数的上下文参数不能用于查找 Scaffold(因为它位于小部件树)。 在这种情况下,以下带有 Builder 的技术可用于为新的作用域提供一个 BuildContext,它在 Scaffold 的“下”:

例子

        Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: Text('Demo')
        ),
        body: Builder(
          // Create an inner BuildContext so that the onPressed methods
          // can refer to the Scaffold with Scaffold.of().
          builder: (BuildContext context) {
            return  Column(
        children : <Widget>[
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: TextField(
              keyboardType: TextInputType.number,
            controller: priceReductionController,
              decoration: InputDecoration(labelText: "Price Reduction",
                  errorText: _validatePrice ? 'value cant be empty' : null,
                  border: new OutlineInputBorder(
                borderRadius: const BorderRadius.all(
                  const Radius.circular(0.0),
                ),
                borderSide: new BorderSide(
                  color: Colors.indigo,
                  width: 1.0,
                ),
              )),
            ),
          ),
...


      );
    }

更有效的解决方案是将您的构建功能拆分为多个小部件。您可以从 flutter docs 中阅读更多相关信息

make (b) 字母小 buildContext 不是 BuildContext 就可以了

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM