firebase - 向Cloud Firestore抖动插入数据时出错?

标签 firebase flutter dart google-cloud-firestore

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

这是我的代码:

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)

enter image description here

最佳答案

从您的错误日志

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. (package:adminbookingpage/screens/addPromo.dart:119:24) E/flutter (13616):



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


        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,
                ),
              )),
            ),
          ),
...


      );
    }

一个更有效的解决方案是将构建函数拆分为几个小部件。您可以阅读更多关于它的信息from flutter docs

关于firebase - 向Cloud Firestore抖动插入数据时出错?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59320448/

相关文章:

firebase - 获得当前用户时未设置我的变量

javascript - Chrome 扩展程序中的 Firebase UI : signInSuccess never called

android - 从 Flutter 应用通过本地网络连接到 Firebase 函数模拟器

iOS 音频/声音不会在后台模式处于事件状态时在后台播放

dart - 如何将 flutter PageView 放入列或行中?当我这样做时,我收到以下错误

dart - 在Dart中创建一组独特的 map

dart - 如何修复 future<int> 类型的值不能分配给 int 类型的变量

firebase - 最大url查询字符串太多众说纷纭?

firebase - Flutter/Dart 应用因 Firebase Date 对象的更改而中断

ios - 未找到模块 'apple_sign_in'