颤振:如何移除等待以利用Firebase脱机持久性?

颤振:如何移除等待以利用Firebase脱机持久性?,firebase,flutter,firebase-realtime-database,async-await,Firebase,Flutter,Firebase Realtime Database,Async Await,我使用的是一个下拉列表(DropDown),其元素从Firebase获得。表单正常工作,但是当internet连接断开时,Firebase脱机持久性属性不工作,CircularProgressIndicator保持活动状态。阅读一些回复,例如,指出不应处理等待,但我不清楚如何实现它: class EstanqueAlimentarPage extends StatefulWidget { @override _EstanqueAlimentarPageState createState

我使用的是一个下拉列表(DropDown),其元素从Firebase获得。表单正常工作,但是当internet连接断开时,Firebase脱机持久性属性不工作,CircularProgressIndicator保持活动状态。阅读一些回复,例如,指出不应处理等待,但我不清楚如何实现它:

class EstanqueAlimentarPage extends StatefulWidget {

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

class _EstanqueAlimentarPageState extends State<EstanqueAlimentarPage> {
  final formKey = GlobalKey<FormState>();
  AlimentoBloc alimentoBloc = new AlimentoBloc();
  AlimentoModel _alimento = new AlimentoModel();
  AlimentarModel alimentar = new AlimentarModel();
  List<AlimentoModel> _alimentoList;
  bool _alimentoDisponible = true;

@override
  void dispose() {
    alimentoBloc.dispose();
    super.dispose();
  }

@override
void initState() {
  _obtenerListaAlimentoUnaVez();
  super.initState();  
}


Future<void> _obtenerListaAlimentoUnaVez() async {
  
  _alimentoList = await alimentoBloc.cargarAlimento(idEmpresa); // Await that I want to eliminate

  if (_alimentoList.length > 0) { // Here appears a BAD STATE error when the internet connection goes from off to on
    _alimento = _alimentoList[0];
    _alimentoDisponible = true;
  } else {
    _alimentoDisponible = false;
  }
  _cargando = false;
  setState(() {});
}

  @override
  Widget build(BuildContext context) {
    
    return Form(
      key: formKey, 
      child: Column(
        children: <Widget> [
          _crearTipoAlimento(_alimentoList),
          SizedBox(height: 8.0),
          _crearComentarios(),
        ]
      )
    ),
    _crearBoton('Guardar'),

  }

  Widget _crearTipoAlimento(List<AlimentoModel> lista) {

    return Container(
      decoration: _cajaBlanca,
      child: 
      !_cargando // If it isn't loading, Dropdown must be displayed
      ? DropdownButtonFormField<AlimentoModel>(
        decoration: InputDecoration(
          labelText: 'Nombre del Alimento',
          contentPadding: EdgeInsets.only(top:5.0),
          prefixIcon: Icon(FontAwesomeIcons.boxOpen, color: Theme.of(context).primaryColor,),
          border: InputBorder.none,
        ),
        value: _alimento,
        items: lista.map((AlimentoModel value) {
          return DropdownMenuItem<AlimentoModel>(
            child: Text(value.nombre),
            value: value,
          );
        }).toList(),
        onChanged: (_alimentoDisponible) ? (AlimentoModel _alimentoSeleccionado) {
          print(_alimentoSeleccionado.nombre);
          _alimento = _alimentoSeleccionado;
          setState(() {});
        } : null,
        disabledHint: Text('No hay Alimento en Bodega'),
        onSaved: (value) {
          alimentar.idAlimento = _alimento.idAlimento;
          alimentar.nombreAlimento = _alimento.nombreRef; 
        }
      )
      : Center (child: CircularProgressIndicator(strokeWidth: 1.0,))

    );
  }

  Widget _crearComentarios() {
    return TextFormField(
      // -- DESIGN OTHER FIELDS -- //
      onSaved: (value) {
        alimentar.comentarios = value;
      }
    ),
    );
  }

  Widget _crearBoton(String texto) {
    return RaisedButton(
        // -- DESIGN -- //
        onPressed: (_guardando) ? null : _submit,
      ),
    );
  }

  void _submit() {

    // CODE TO WRITE FORM IN FIREBASE
  }
}
class EstanquirementArpage扩展StatefulWidget{
@凌驾
_EstanquirementArpageState createState()=>\u EstanquirementArpageState();
}
类的扩展状态{
final formKey=GlobalKey();
AlimentoBloc AlimentoBloc=新的AlimentoBloc();
AlimentoModel_alimento=新的AlimentoModel();
AlimentarModel alimentar=新的AlimentarModel();
清单(营养清单),;
bool_alimentoDisponible=true;
@凌驾
无效处置(){
alimentoBloc.dispose();
super.dispose();
}
@凌驾
void initState(){
_obtenerListaalimentounaez();
super.initState();
}
Future _obtenerListaalimentounaez()异步{
_alimentoList=等待alimentoBloc.cargarAlimento(idEmpresa);//等待我想要消除的
如果(_alimentoList.length>0){//当internet连接从关闭变为打开时,此处会出现错误状态
_alimento=_alimentoList[0];
_AlimentoDisposible=true;
}否则{
_alimentoDisponible=假;
}
_cargando=假;
setState((){});
}
@凌驾
小部件构建(构建上下文){
报税表(
key:formKey,
子:列(
儿童:[
_crearTipoAlimento(_alimentoList),
尺寸箱(高度:8.0),
_crearComentarios(),
]
)
),
_crearBoton(“Guardar”),
}
小部件(列表A){
返回容器(
装饰:卡贾布兰卡,
儿童:
!\u cargando//如果未加载,则必须显示下拉列表
?下拉按钮窗体字段(
装饰:输入装饰(
标签文字:“阿利门托的名字”,
contentPadding:仅限边集(顶部:5.0),
前缀:图标(FontAwesomeIcons.boxOpen,颜色:Theme.of(context.primaryColor,),
边框:InputBorder.none,
),
值:_alimento,
项目:lista.map((模型值){
返回下拉菜单项(
子项:文本(value.nombre),
价值:价值,
);
}).toList(),
一旦更改:(\u AlimentoDisposable)?(AlimentoModel\u AlimentoSelecionado){
印刷品(_alimentoSeleccionado.nombre);
_alimento=_alimentoSeleccionado;
setState((){});
}:null,
disabledHint:Text('No hay Alimento en Bodega'),
已保存:(值){
alimentar.idAlimento=_alimento.idAlimento;
alimentar.nombreAlimento=\u alimento.nombref;
}
)
:居中(子项:圆压指示器(冲程宽度:1.0,)
);
}
Widget_crearComentarios(){
返回TextFormField(
//--设计其他领域--//
已保存:(值){
营养素=价值;
}
),
);
}
Widget_crearBoton(字符串texto){
返回上升按钮(
//--设计--//
按下按钮:(\u guardando)?空:\u提交,
),
);
}
作废(提交){
//在FIREBASE中编写表单的代码
}
}
my BLOC的功能代码为:

  Future<List<AlimentoModel>> cargarAlimento(String idEmpresa, [String filtro]) async {
    final alimento = await _alimentoProvider.cargarAlimento(idEmpresa, filtro); //It's one await more
    _alimentoController.sink.add(alimento);
    return alimento;
  }
Future cargarAlimento(字符串idEmpresa,[String filtro])异步{
final alimento=wait _alimentoProvider.cargarAlimento(idEmpresa,filtro);//这是一个等待更多
_alimento控制器.sink.add(alimento);
归还赡养费;
}
而来自提供者的查询是:

Future<List<AlimentoModel>> cargarAlimento(String idEmpresa, [String filtro]) async {

    Query resp;
    final List<AlimentoModel> alimento = new List(); 
    resp = db.child('empresas').child(idEmpresa).child('bodega/1').child('alimento')
            .orderByChild('cantidad').startAt(0.000001);
 
  return resp.once().then((snapshot) {

      if (snapshot.value == null) return [];
      if (snapshot.value['error'] != null) return []; 

      snapshot.value.forEach((id, alim){
        final temp = AlimentoModel.fromJson(Map<String,dynamic>.from(alim));
        temp.idAlimento = id;

        alimento.add(temp);
      });
      return alimento;
  }); 
Future cargarAlimento(字符串idEmpresa,[String filtro])异步{
查询响应;
最终列表alimento=新列表();
resp=db.child('empresas')。child(idEmpresa)。child('bodega/1')。child('alimento'))
.orderByChild('cantidad').startAt(0.000001);
返回resp.one()然后((快照){
if(snapshot.value==null)返回[];
if(snapshot.value['error']!=null)返回[];
snapshot.value.forEach((id,alim){
final temp=AlimentoModel.fromJson(Map.from(alim));
温度idAlimento=id;
添加营养素(温度);
});
归还赡养费;
}); 

脱机使用Firebase时,您仅在更改服务器的事情上(例如,创建或更新记录)省略
wait
。因此,您不会等待服务器说“是的,我写了它”,而是假设它已写

但是,在您的情况下,您不是在写入数据,而是在读取数据。在您的示例中,您必须保持
等待
。加载数据的方式有
orderByChild
startAt
,这些可能会阻止脱机加载。通常,如果数据已经在缓存中,您会得到它:


您提到了一个
坏状态错误
,如果您提供了该错误,我们可能能够更好地查明问题。

您提供的链接讨论了事务,当您未连接到服务器时,这些事务将不起作用。您的代码不使用事务,因此就我所见,不会受到链接中所述内容的影响。什么不起作用在运行代码时处理它?谢谢你,弗兰克!!谢谢弗兰克。我不能让下拉列表在连接脱机时起作用。除了这个链接,a还提到应该避免事务和等待。这些链接中没有足够的上下文,无法理解它们在这里的应用。在连接脱机时,代码中的哪一行不起作用你离线了?这行…\u alimentoList=wait alimentoBloc.cargarAlimento(idEmpresa);它做什么?你期望它做什么?如果你
打印代码中显示你不期望的东西,通常最容易得到帮助。