【发布时间】:2022-06-26 13:37:05
【问题描述】:
我是 Flutter 初学者,我正在 Udemy 学习“Flutter & Dart - 完整指南 [2022 版]”课程(如果您知道我在第 10 节第 242 课“发送 POST 请求”的课程。这个这是我第一次使用 Firebase 和数据库,我在这个问题上停留了很长一段时间。我们在课程的前面部分构建了一个基本的商店应用程序,现在我们应该在添加时向我们的 Firebase 实时数据库发送一个 Post 请求一个新产品到我们的应用程序。我们应该在我们的数据库中添加一些关于产品的基本信息。当我尝试添加一个新产品时,没有任何反应,我的数据库中没有数据,我的应用程序中没有新产品(将产品添加到应用程序发生在发送 Post 请求后立即使用相同的功能)。我的终端没有错误,只有下面一行。
I/flutter (11699): ...
在添加 http 包和编写上一课的发布请求代码之前,我能够将产品添加到应用程序。这些是我的调试、数据库规则和发送 post 请求的函数。
void addProduct(Product product) {
final url = Uri.parse(
'https://flutter-update-ca55a-default-rtdb.firebaseio.com/products.json');
http.post(
url,
body: json.encode({
'title': product.title,
'description': product.description,
'imageUrl': product.imageUrl,
'price': product.price,
'isFavorite': product.isFavorite,
}),
);
final newProduct = Product(
id: DateTime.now().toString(),
title: product.title,
description: product.description,
price: product.price,
imageUrl: product.imageUrl);
_items.add(newProduct);
notifyListeners();
}
我尝试了课程构造函数示例代码,但没有成功。然后我尝试禁用我的防火墙,将我的数据库规则更改为我的问题中看到的,仍然是同样的问题。我什至不知道我的代码是否正在与 firebase 通信。
编辑: 有时我也会在终端上获得最新的文本,并在下面添加屏幕截图:
编辑 2: 所以我创建了一个空项目来查看我的计算机是否正在与 firebase 通信并且它工作正常,我从单屏应用程序将信息添加到我的数据库中。我担心我的 Shop 应用程序中有一个逻辑错误(很可能在我使用 addProduct 函数的屏幕上),所以如果您看到错误,我会发布代码,请警告我。这是edit-product-screen,我通过provider使用addProduct函数。
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../providers/product.dart';
import '../providers/product_provider.dart';
class EditProductScreen extends StatefulWidget {
static const String routeName = '/edit-product-screen';
@override
State<EditProductScreen> createState() => _EditProductScreenState();
}
class _EditProductScreenState extends State<EditProductScreen> {
//final _priceFocusNode = FocusNode();
//final _descriptionFocusNode = FocusNode();
final _imageUrlController = TextEditingController();
//final _imageUrlFocusNode = FocusNode();
final _form = GlobalKey<FormState>();
var _editedProduct =
Product(id: '', title: '', description: '', price: 0, imageUrl: '');
var _isInit = true;
var _isloading = false;
var _initValues = {
'title': '',
'description': '',
'price': '',
'imageUrl': '',
};
@override
void initState() {
//_imageUrlFocusNode.addListener(_updateImageUrl);
super.initState();
}
@override
void didChangeDependencies() {
if (_isInit) {
final String? productId =
ModalRoute.of(context)!.settings.arguments as String?;
if (productId != null) {
_editedProduct = Provider.of<ProductProvider>(context, listen: false)
.findbyID(productId);
_initValues = {
'title': _editedProduct.title,
'description': _editedProduct.description,
'price': _editedProduct.price.toString(),
// 'imageUrl': _editedProduct.imageUrl,
'imageUrl': '',
};
_imageUrlController.text = _editedProduct.imageUrl;
}
}
_isInit = false;
super.didChangeDependencies();
}
// @override
// void dispose() {
// _imageUrlFocusNode.removeListener(_updateImageUrl);
// _priceFocusNode.dispose();
// _descriptionFocusNode.dispose();
// _imageUrlController.dispose();
// _imageUrlFocusNode.dispose();
// super.dispose();
// }
void _updateImageUrl() {
// if (!_imageUrlFocusNode.hasFocus) {
// if ((!_imageUrlController.text.startsWith('http') &&
// !_imageUrlController.text.startsWith('https')) ||
// (!_imageUrlController.text.endsWith('.png') &&
// !_imageUrlController.text.endsWith('.jpg') &&
// !_imageUrlController.text.endsWith('.jpeg'))) {
// return;
// }
setState(() {});
//}
}
void _saveForm() {
final isValid = _form.currentState!.validate();
if (!isValid) {
return;
}
_form.currentState!.save();
setState(() {
_isloading = true;
});
if (_editedProduct.id != null) {
//var olan bir product editleniyor
Provider.of<ProductProvider>(context, listen: false)
.updateProduct(_editedProduct.id, _editedProduct);
setState(() {
_isloading = false;
});
Navigator.of(context).pop();
} else {
//yeni bir product oluşturuluyor.
Provider.of<ProductProvider>(context, listen: false)
.addProduct(_editedProduct)
.catchError((error) {
return showDialog<Null>(
context: context,
builder: (ctx) => AlertDialog(
title: Text('An Error Occured'),
content: Text(error.toString()),
actions: [
FlatButton(
onPressed: () {
Navigator.of(ctx).pop();
},
child: Text('Okay'))
],
),
);
}).then((_) {
setState(() {
_isloading = false;
});
Navigator.of(context).pop();
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Edit Products'),
actions: [
IconButton(
onPressed: _saveForm,
icon: Icon(Icons.save),
),
],
),
body: _isloading
? Center(
child: CircularProgressIndicator(),
)
: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _form,
child: ListView(
children: [
TextFormField(
initialValue: _initValues['title'],
decoration: InputDecoration(labelText: 'Title'),
validator: (value) {
if (value!.isEmpty) {
return 'Please enter a title';
}
return null;
},
textInputAction: TextInputAction.next,
// onFieldSubmitted: (_) {
// FocusScope.of(context).requestFocus(_priceFocusNode);
// },
onSaved: (value) {
_editedProduct = Product(
title: value as String,
price: _editedProduct.price,
description: _editedProduct.description,
imageUrl: _editedProduct.imageUrl,
id: _editedProduct.id,
isFavorite: _editedProduct.isFavorite,
);
},
),
TextFormField(
initialValue: _initValues['price'],
decoration: InputDecoration(labelText: 'Price'),
textInputAction: TextInputAction.next,
keyboardType: TextInputType.number,
//focusNode: _priceFocusNode,
// onFieldSubmitted: (_) {
// FocusScope.of(context).requestFocus(_descriptionFocusNode);
// },
validator: (value) {
if (value!.isEmpty) {
return 'Please enter a price';
}
if (double.tryParse(value) == null) {
return 'Please enter a valid number';
}
if (double.parse(value) <= 0) {
return 'Plase enter a number greater than zero';
}
return null;
},
onSaved: (value) {
_editedProduct = Product(
title: _editedProduct.title,
price: double.parse(value as String),
description: _editedProduct.description,
imageUrl: _editedProduct.imageUrl,
id: _editedProduct.id,
isFavorite: _editedProduct.isFavorite,
);
},
),
TextFormField(
initialValue: _initValues['description'],
decoration: InputDecoration(labelText: 'Description'),
maxLines: 3,
validator: (value) {
if (value!.isEmpty) {
return 'Please enter a description';
}
if (value.length < 10) {
return 'Your description must be longer then 10 characters';
}
return null;
},
textInputAction: TextInputAction.next,
//focusNode: _descriptionFocusNode,
keyboardType: TextInputType.multiline,
onSaved: (value) {
_editedProduct = Product(
title: _editedProduct.title,
price: _editedProduct.price,
description: value as String,
imageUrl: _editedProduct.imageUrl,
id: _editedProduct.id,
isFavorite: _editedProduct.isFavorite,
);
},
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Container(
width: 100,
height: 100,
margin: EdgeInsets.only(top: 8, right: 10),
decoration: BoxDecoration(
border: Border.all(width: 1, color: Colors.grey),
),
child: _imageUrlController.text.isEmpty
? Text('Enter a URL')
: FittedBox(
child: Image.network(
_imageUrlController.text,
fit: BoxFit.cover,
),
),
),
Expanded(
child: TextFormField(
decoration: InputDecoration(labelText: 'Image URL'),
validator: (value) {
if (value!.isEmpty) {
return 'Please enter a image url';
}
if (!value.startsWith('http') &&
!value.startsWith('https')) {
return 'Please enter a valid image url';
}
return null;
},
keyboardType: TextInputType.url,
textInputAction: TextInputAction.done,
controller: _imageUrlController,
//focusNode: _imageUrlFocusNode,
onFieldSubmitted: (_) {
_saveForm();
},
onSaved: (value) {
_editedProduct = Product(
title: _editedProduct.title,
price: _editedProduct.price,
description: _editedProduct.description,
imageUrl: value as String,
id: _editedProduct.id,
isFavorite: _editedProduct.isFavorite,
);
},
),
),
],
)
],
),
),
),
);
}
}
这是最新版的addProduct函数
Future<void> addProduct(Product product) async {
final url = Uri.parse(
'https://flutter-update-ca55a-default-rtdb.firebaseio.com/products2.json');
try {
final response = await http.post(
url,
body: json.encode({
'title': product.title,
'description': product.description,
'imageUrl': product.imageUrl,
'price': product.price,
'isFavorite': product.isFavorite,
}),
);
print(json.decode(response.body));
final newProduct = Product(
id: DateTime.now().toString(),
title: product.title,
description: product.description,
price: product.price,
imageUrl: product.imageUrl);
_items.add(newProduct);
notifyListeners();
} catch (error) {
print(error);
throw error;
}
}
【问题讨论】:
标签: firebase flutter firebase-realtime-database