https://codekodo.tistory.com/91
์ง๊ธ๊น์ง๋ Local์์ ์งํํ๋๋ฐ Firebase๋ฅผ ์ด์ฉํ์ฌ Server์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋๋ก ์ฝ๋๋ฅผ ์์ ํ๋ค.
์ฐ์ ์ผ์ข ์ Controller ์ญํ ์ ์ํํ๋ Provider๋ก ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ๋ค.
์๋ฅผ ๋ค์ด ์๋ฒ์ ์ ์ฅ๋ ์ํ์ ๊ฐ์ ธ์ฌ ์ ์๋๋ก ๊ตฌํํ๋ค.
import 'package:flutter/material.dart';
import '/models/http_exception.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'product.dart';
class Products with ChangeNotifier {
List<Product> _items = [
// Product(
// id: 'p1',
// title: '๋์ฌ ๋ฐฐํฅ๋ ๋น๋น๋ฉด, 32๊ฐ์
',
// description: '์์ฒญ ์์ํ ๋น๋น๋ฉด ์กด๋งํฑ์!',
// price: 19020,
// imageUrl:
// 'https://thumbnail8.coupangcdn.com/thumbnails/remote/230x230ex/image/retail/images/255828096400583-70f3975f-3357-4101-bf29-d1dbc7bf94d8.jpg',
// ),
// Product(
// id: 'p2',
// title: '๋์ฌ ์งฌ๋ฝ๊ฑด๋ฉด, 32๊ฐ์
',
// description: '์ด๊ฒ์ด ์งฌ๋ฝ์ธ๊ฐ ์ง์ฅ์ธ๊ฐ ๋ชจ๋ฅด๊ฒ ๋ค',
// price: 20300,
// imageUrl:
// 'https://thumbnail6.coupangcdn.com/thumbnails/remote/230x230ex/image/rs_quotation_api/xlezetna/983616a9d6cb4879b8ec897b0f190912.jpg',
// ),
// Product(
// id: 'p3',
// title: '์ ๋ผ๋ฉด ๋ธ๋ ๋๋ถ๊น์น, 4๊ฐ์
',
// description: 'ํํธ์ํ ์ ๋ผ๋ฉด ๋ธ๋์ ํ์์!',
// price: 3800,
// imageUrl:
// 'https://thumbnail7.coupangcdn.com/thumbnails/remote/230x230ex/image/retail/images/2020/11/16/18/8/c199d767-22d4-4d94-9df7-8757f5db3d34.jpg',
// ),
// Product(
// id: 'p4',
// title: '์๋ชฌ๋๋ธ๋ฆฌ์ฆ ๋ดํธ๋ฆฌ ์์ด์ฌ์ ',
// description: '๋ค์ด์ดํธ ๋๊ฐ์',
// price: 15480,
// imageUrl:
// 'https://thumbnail6.coupangcdn.com/thumbnails/remote/230x230ex/image/retail/images/2020/10/22/17/8/e705de8a-ec4c-4cfd-a38f-42afc47215df.jpg',
// ),
// Product(
// id: 'p5',
// title: 'ํ๋ ์์ง ๋ํฐ ํ๊ฐ๋ ๋ถ๋์ ๊ณจ',
// description: '์ง์์ ํด๋จน๋ ๊ฐํธ ๋ถ๋์ฐ๊ฐ!',
// price: 10900,
// imageUrl:
// 'https://thumbnail8.coupangcdn.com/thumbnails/remote/230x230ex/image/retail/images/2020/06/18/12/9/9f4cd406-34aa-4e3e-ba20-2c5ebeff0234.jpg',
// ),
// Product(
// id: 'p6',
// title: '๋ฏธํธํฌ์ ์๋ ์ผ๊ฒน์ด',
// description: '๋ค์ด์ดํธ ๋๊ฐ์',
// price: 14900,
// imageUrl:
// 'https://thumbnail6.coupangcdn.com/thumbnails/remote/230x230ex/image/retail/images/2020/10/21/16/3/88432c7e-584a-4748-9db2-9760f8080ac3.jpg',
// ),
// Product(
// id: 'p7',
// title: 'ํํ ํ
์ฐ B5',
// description: '์ฌ๋๋ฆ ์ ์ฉ์ธ๊ฐ?',
// price: 9330,
// imageUrl:
// 'https://thumbnail6.coupangcdn.com/thumbnails/remote/230x230ex/image/vendor_inventory/images/2019/03/20/13/1/57ecf457-bb41-4ba8-9b65-63597c024cee.jpg'),
// Product(
// id: 'p8',
// title: 'ํด๋ฉธ์ ์นผ๋ ํ๋
ธ์นด๋ฏธ',
// description: '๊ท์นผ ์ ํ์ด๋ผ๋ฉฐ',
// price: 125000,
// imageUrl:
// 'https://thumbnail6.coupangcdn.com/thumbnails/remote/230x230ex/image/retail/images/2021/07/13/10/4/12387f17-6f35-488c-876f-8296bd727d7c.jpg'),
// Product(
// id: 'p9',
// title: 'ํํ๋๋ ์ค๋งํธ ์ฒด์ง๋ฐฉ ์ธก์ ๊ธฐ',
// description: '๋ค์ด์ดํธ ๋๊ฐ์',
// price: 13660,
// imageUrl:
// 'https://thumbnail9.coupangcdn.com/thumbnails/remote/230x230ex/image/retail/images/519187041074607-0c17571c-5e95-469e-a940-99b2883aa25b.jpg',
// ),
// Product(
// id: 'p10',
// title: '์ค์ค๋ฏธ LCD ๋๋ก์ ํ
์ด๋ธ',
// description: '๊ทธ๋ฆผ์ด ๋๋ฌด ์ข์',
// price: 22950,
// imageUrl:
// 'https://thumbnail7.coupangcdn.com/thumbnails/remote/230x230ex/image/retail/images/2020/11/04/10/5/8b59da3d-c676-4529-986d-6969690a6733.jpg'),
// Product(
// id: 'p11',
// title: '๋ํ
๋ ์ค์์น ํผํํธ ์ํผ๋ณผ',
// description: '๊ณง ํ์ ์์!',
// price: 38000,
// imageUrl:
// 'https://thumbnail7.coupangcdn.com/thumbnails/remote/300x300ex/image/retail/images/2021/07/14/10/8/311f8e83-9b5f-4fbb-9bda-50c74560bc08.jpg'),
// Product(
// id: 'p12',
// title: 'Apple ์ ํ USB-C ์ผ์ด๋ธ',
// description: '์ ํ ์ผ์ด๋ธ',
// price: 19500,
// imageUrl:
// 'https://thumbnail10.coupangcdn.com/thumbnails/remote/300x300ex/image/retail/images/330677074620956-bc96f542-d67b-45d7-91ae-f91d39b59f5b.jpg'),
// Product(
// id: 'p13',
// title: '์ ํ์์น SE, GPS',
// description: '2021๋
์ต์ ํ',
// price: 345900,
// imageUrl:
// 'https://thumbnail7.coupangcdn.com/thumbnails/remote/300x300ex/image/retail/images/7696374737960-06c26f91-d1ad-45c8-bf34-39ee275d068a.jpg'),
];
List<Product> get items {
return [..._items];
}
List<Product> get favoriteItems {
return _items.where((productItem) => productItem.isFavorite).toList();
}
Product findById(String id) {
return _items.firstWhere((element) => element.id == id);
}
final String autoToken;
Products(this.autoToken, this._items);
// void showFavoritesOnly() {
// _showFavoritesOnly = true;
// notifyListeners();
// }
//
// void showAll() {
// _showFavoritesOnly = false;
// notifyListeners();
// }
//
Future<void> fetchAndSetProducts() async {
final url =
'https://myfourthflutterapp-default-rtdb.firebaseio.com/products.json?auth=$autoToken';
try {
final response = await http.get(url);
final extractData = json.decode(response.body) as Map<String, dynamic>;
final List<Product> loadedProducts = [];
if (extractData == null) {
return;
}
extractData.forEach((key, value) {
loadedProducts.add(Product(
id: key,
title: value['title'],
description: value['description'],
price: value['price'],
isFavorite: value['isFavorite'],
imageUrl: value['imageUrl'],
));
});
_items = loadedProducts;
notifyListeners();
} catch (error) {
throw (error);
}
}
Future<void> addProduct(Product product) async {
final url =
'https://myfourthflutterapp-default-rtdb.firebaseio.com/products.json?auth=$autoToken';
try {
final response = await http.post(
url,
body: json.encode({
'title': product.title,
'price': product.price,
'description': product.description,
'imageUrl': product.imageUrl,
'isFavorite': product.isFavorite,
}),
);
final newProduct = Product(
id: json.decode(response.body)['name'],
title: product.title,
price: product.price,
description: product.description,
imageUrl: product.imageUrl,
);
_items.add(newProduct);
notifyListeners();
} catch (error) {
throw error;
}
}
Future<void> updateProduct(String id, Product newProduct) async {
final prodIndex = _items.indexWhere((prod) => prod.id == id);
if (prodIndex >= 0) {
final url =
'https://myfourthflutterapp-default-rtdb.firebaseio.com/products/$id.json?auth=$autoToken';
await http.patch(url,
body: json.encode({
'title': newProduct.title,
'description': newProduct.description,
'price': newProduct.price,
'imageUrl': newProduct.imageUrl,
}));
_items[prodIndex] = newProduct;
notifyListeners();
} else {
print('...');
}
}
Future<void> deleteProduct(String id) async {
final url =
'https://myfourthflutterapp-default-rtdb.firebaseio.com/products/$id.json?auth=$autoToken';
final existingProductIndex = _items.indexWhere((prod) => prod.id == id);
var existingProduct = _items[existingProductIndex];
final response = await http.delete(url);
_items.removeAt(existingProductIndex);
notifyListeners();
if (response.statusCode >= 400) {
_items.insert(existingProductIndex, existingProduct);
notifyListeners();
throw HttpException('์ํ์ ์ญ์ ํ ์ ์์ต๋๋ค.');
}
existingProduct = null;
}
}
์ฃผ์ ๋ถ๋ถ์ ๊ธฐ์กด์ ์ฌ์ฉํ๋ ๋๋ฏธ ๋ฐ์ดํฐ์ด๋ค.
fetchAndSetProducts๋ ์ํ ๋ชฉ๋ก์ ๊ฐ์ ธ์ค๋ ๋ฉ์๋๋ก์จ http ํต์ ์ get ๋ฐฉ์์ ์ด์ฉํ์ฌ
json ํํ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์จ๋ค.
์ดํ ํ์ฑ์ ํตํด ๋ฆฌ์คํธํํ๋ก ์ ์ฅํ๋ค.
addProduct๋ ์ํ์ ์ถ๊ฐํ๋ ๋ฉ์๋์ด๋ค.
์ด๋ฒ์ post ๋ฐฉ์์ ์ด์ฉํ์ฌ json์ body์ ์ถ๊ฐํ ์ํ ๋ฐ์ดํฐ ์ ๋ณด๋ฅผ ๋ฃ์ด์ ๋ณด๋ธ๋ค.
updateProduct๋ ๊ธฐ์กด์ ์๋ ์ํ์ ์ ๋ณด๋ฅผ ์์ ํ๋ ๋ฉ์๋์ด๋ค.
patch ๋ฐฉ์์ ์ด์ฉํด์ ๋ฐ์ดํฐ๋ฅผ ์์ ํ๋ค.
deleteProduct๋ ์ํ์ ์ ๊ฑฐํ๋ ๋ฉ์๋๋ก delete ๋ฐฉ์์ ์ด์ฉํด์ ์๋ฒ์ ์ ์ฅ๋ ์ํ์ ์ ๊ฑฐํ๋ค.
์ค์ ์ค์๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ณด๋ฉด ์ ์์ ์ผ๋ก ์ ์ฅ๋์ด ์๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
์์ค์ฝ๋๋ ์๋ ๋งํฌ๋ฅผ ํตํด ์ ์ํ๋ฉด ํ์ธํ ์ ์๋ค.
https://github.com/k906506/2021-Summer-Flutter-Study/tree/master/myfourthflutterapp
'โน๏ธ ๋ผ์ดํ > 2021 ์ฌ๋ฆ๋ฐฉํ ๋ชจ๊ฐ์ฝ(๊ฐ์ธ)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์ฝ๋ ํ๊ตฌ๋ง 2] 5์ฃผ์ฐจ - Flutter : Shop App 2 (0) | 2021.08.10 |
---|---|
[์ฝ๋ ํ๊ตฌ๋ง 2] 4์ฃผ์ฐจ - Flutter : Shop App 1 (0) | 2021.07.28 |
[์ฝ๋ ํ๊ตฌ๋ง 2] 3์ฃผ์ฐจ - Flutter : Personal Expense App (2) | 2021.07.22 |
[์ฝ๋ ํ๊ตฌ๋ง 2] 2์ฃผ์ฐจ - Flutter : Personal Expense App (0) | 2021.07.15 |
[์ฝ๋ ํ๊ตฌ๋ง 2] 1์ฃผ์ฐจ - Flutter : Quiz App (0) | 2021.07.07 |