我正在使用下拉列表 (DropDown),其元素是从 Firebase 获取的。该表单工作正常,但是当互联网连接丢失时,Firebase 离线持久性属性不起作用并且 CircularProgressIndicator 保持事件状态。阅读一些回复,例如 Using Offline Persistence in Firestore in a Flutter App ,表示不应处理等待 ,但是我不清楚如何实现它:
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
}
}
我的 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;
}
来自 PROVIDER 的查询是: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;
});
最佳答案
离线使用 Firebase 时,请省略 await
仅在更改服务器的事情上(例如,创建或更新记录)。所以你不会等待服务器说“是我写的”,你假设它已经写好了。
但是,就您而言,您不是在写入数据,而是在读取数据。您必须保留 await
在你的例子中。你加载数据的方式有 orderByChild
和 startAt
,也许那些正在阻止离线加载。通常,如果它已经在缓存中,你就会得到它:https://firebase.google.com/docs/firestore/manage-data/enable-offline#get_offline_data
你提到了 BAD STATE error
,也许如果您提供该信息,我们可能能够更好地查明问题。
关于firebase - Flutter:如何删除等待以利用 Firebase 离线持久性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63205559/