【发布时间】:2020-11-15 07:05:33
【问题描述】:
我正在开发一个 Agro 应用程序,当我观看 Firebase 宣传视频时,我真的很喜欢他们描述应用程序的方式,即使没有互联网(离线持久性)也是如此。
为了开发我使用过的应用程序:
- 颤动
- Firebase API REST(http 插件)
- 向 API 发出请求的提供者
- BLOC 模式
我的应用程序已经基本完成了,但是我注意到当没有互联网时会出现错误:
SocketException:主机查找失败:'node1.bitcoiin.com'(操作系统错误:没有与主机名关联的地址,errno = 7)
Medium 上的@IshwarChandra 澄清了我:
当您在 Firebase 中使用离线持久性时,请勿使用事务 或等待回复。
对吗?真的可以在不使用等待的情况下从 Firebase 检索数据吗?我问这个是因为我在某些情况下实现了 BLOC 模式,从而从用户界面中删除了等待。然而,它背后总是调用一个等待加载数据的 Provider。
另一方面,StackOverFlow 的一位开发人员向我表示,离线持久性管理只能使用 Flutter SDK 和
这是不可能的(或者需要太多的编程)来实现 就像我一直在使用它一样,它与 REST API 一起使用。
这个说法正确吗?如果是这样,我有以下疑问:
-
是否有文档或提示可以让我轻松地将 http REST Firebase API 请求(我主要在 Provider 中)迁移到 Flutter 中的 Firebase SDK?
-
我可以保留我正在使用的 BLOC 和 PROVIDER 的架构吗?
-
在进行更改之前还有其他提示吗?
我的 Providers 上的示例代码供您参考:
import 'dart:convert';
import 'package:aplians_fish/src/preferencias_usuario/preferencias_usuario.dart';
import 'package:http/http.dart' as http;
import 'package:aplians_fish/src/models/alimentar_model.dart';
class AlimentarProvider {
final String _url ='https://apliansdb.firebaseio.com';
final _prefs = new PreferenciasUsuario();
// ==========================================================
// ======================== CREATE ==========================
// ==========================================================
Future<bool> crearAlimentar(AlimentarModel alimentar, String idEmpresa, String idEstanque) async {
final url ='$_url/empresas/$idEmpresa/estanques/$idEstanque/loteActual/alimentacion.json?auth=${_prefs.token}';
final resp = await http.post(url, body: alimentarModelToJson(alimentar));
final decodedData = json.decode(resp.body); // Da la respuesta, sea un cargue o un error
print(decodedData);
return true;
}
// ==========================================================
// ================== READ =====================
// ==========================================================
Future<List<AlimentarModel>> cargarAlimentar(String idEmpresa, String idEstanque) async {
final url ='$_url/empresas/$idEmpresa/estanques/$idEstanque/loteActual/alimentacion.json?auth=${_prefs.token}';
final resp = await http.get(url);
final Map<String, dynamic> decodedData = json.decode(resp.body);
final List<AlimentarModel> alimentar = new List();
if (decodedData == null) return [];
if (decodedData['error'] != null) return [];
decodedData.forEach((id, alim){
final temp = AlimentarModel.fromJson(alim);
temp.idAlimentar = id;
alimentar.add(temp);
});
return alimentar;
}
// ==========================================================
// =========================== UPDATE =======================
// ==========================================================
Future<bool> editarAlimentar(String idEmpresa, String idEstanque, AlimentarModel alimentar) async {
final url = '$_url/empresas/$idEmpresa/estanques/$idEstanque/loteActual/alimentacion/${alimentar.idAlimentar}.json?auth=${_prefs.token}';
final resp = await http.put(url, body: alimentarModelToJson(alimentar));
final decodedData = json.decode(resp.body);
print(decodedData);
return true;
}
// ==========================================================
// ================== DELETE =======================
// ==========================================================
Future<bool> borrarAlimentar(String idEmpresa, String idEstanque, String id) async {
final url = '$_url/empresas/$idEmpresa/estanques/$idEstanque/loteActual/alimentacion/$id.json?auth=${_prefs.token}';
final resp = await http.delete(url);
print(json.decode(resp.body));
return true;
}
}
而且,这就是我使用 BLOC 的方式:
import 'package:rxdart/rxdart.dart';
import 'package:aplians_fish/src/models/alimentar_model.dart';
import 'package:aplians_fish/src/providers/alimentar_provider.dart';
class AlimentarBloc {
final _alimentarController = new BehaviorSubject<List<AlimentarModel>>();
final _cargandoController = new BehaviorSubject<bool>();
final _alimentarProvider = new AlimentarProvider();
Stream <List<AlimentarModel>> get alimentarStream => _alimentarController.stream;
Stream <bool> get cargando => _cargandoController.stream;
Future<List<AlimentarModel>> cargarAlimentar(String idEmpresa, String idEstanque) async {
final alimentar = await _alimentarProvider.cargarAlimentar(idEmpresa, idEstanque);
// ahora hay que insertar estos productos al stream...
_alimentarController.sink.add(alimentar);
return alimentar;
}
Future<bool> crearAlimentar(AlimentarModel alimentar, String idEmpresa, String idEstanque) async {
_cargandoController.sink.add(true);
await _alimentarProvider.crearAlimentar(alimentar, idEmpresa, idEstanque);
_cargandoController.sink.add(false); //este es útil para bloquear botones cuando se esté cargando
// esto se hace para notificar que está cargando el producto y de esa forma espere
return true;
}
void editarAlimentar(String idEmpresa, String idEstanque, AlimentarModel alimentar) async {
_cargandoController.sink.add(true);
await _alimentarProvider.editarAlimentar(idEmpresa, idEstanque, alimentar);
_cargandoController.sink.add(false);
// esto se hace para notificar que está cargando el producto y de esa forma espere
}
Future<bool> borrarAlimentar(String idEmpresa, String idEstanque, String id) async {
// _cargandoController.sink.add(true);
await _alimentarProvider.borrarAlimentar(idEmpresa, idEstanque, id);
// _cargandoController.sink.add(false);
// no se requieren los controllers porque para la persona al desplazar, siente que ya se borró
return true;
}
dispose() {
_alimentarController?.close();
_cargandoController?.close();
}
}
【问题讨论】:
标签: firebase flutter dart firebase-realtime-database sdk