Firestore Map Flutter - arrays

Hi Everyone am stuck with this problem am trying to write data this way
Current type
but I always get this
what i get
am using flutter and this is my code
_fetch() async {
final user = await FirebaseAuth.instance.currentUser;
var map = new Map<String, dynamic>();
List<String> productName = [];
map['productName'] = productName;
Stream<QuerySnapshot> productRef = FirebaseFirestore.instance
.collection("cart")
.where('userId', isEqualTo: user?.uid)
.snapshots();
productRef.forEach((field) {
field.docs.asMap().forEach((index, data) {
productName.add(field.docs[index]["name"]);
print(productName);
});
});
getData() async {
return await FirebaseFirestore.instance
.collection('cart')
.where('userId', isEqualTo: user?.uid)
.get();
}
getData().then((QuerySnapshot querySnapshot) {
querySnapshot.docs.forEach((doc) {
var names = doc["name"];
var prices = doc["price"];
FirebaseFirestore.instance.collection('ordersNami').doc().set({
"userId": FirebaseAuth.instance.currentUser?.uid,
"orders": [
{"productName": names, "productPrice": prices},
],
}, SetOptions(merge: true));
});
});
}
i'll explain how it works i have a cart collection and documents field are unique i need to put all the cart products in the structure in first picture

Related

Read firebase doc and copy the data into dart list

How can I read the data of my Firebase document and put the data in a local list/array?
my firebase docs
To get all data from Firestore.
FirebaseFirestore.instance
.collection("users")
.get()
.then((value) {
print(value.docs);
for (var element in value.docs) {
print(element.id);// you will get all ids here
}
});
If you want to upload one particular data from Firestore.
FirebaseFirestore.instance
.collection("users")
.where("uid",
isEqualTo: 'your_uid')
.get()
.then((value) {
print(value.docs);
for (var element in value.docs) {
print(element.id); // single id of that collection
}
});
I have tried this once....
check if this is the same u looking for
List<String> list=[];
final snapshot = await FirebaseFirestore.instance
.collection("users").get();
for(int x=0;x<snapshot.docs.length;x++)
{
list.add(snapshot.docs[x].id);
}
print(list);

How to get all subcollection documents with subcollection name as a date? [duplicate]

Say I have this minimal database stored in Cloud Firestore. How could I retrieve the names of subCollection1 and subCollection2?
rootCollection {
aDocument: {
someField: { value: 1 },
anotherField: { value: 2 }
subCollection1: ...,
subCollection2: ...,
}
}
I would expect to be able to just read the ids off of aDocument, but only the fields show up when I get() the document.
rootRef.doc('aDocument').get()
.then(doc =>
// only logs [ "someField", "anotherField" ], no collections
console.log( Object.keys(doc.data()) )
)
It is not currently supported to get a list of (sub)collections from Firestore in the client SDKs (Web, iOS, Android).
In server-side SDKs this functionality does exist. For example, in Node.js you'll be after the ListCollectionIds method:
var firestore = require('firestore.v1beta1');
var client = firestore.v1beta1({
// optional auth parameters.
});
// Iterate over all elements.
var formattedParent = client.anyPathPath("[PROJECT]", "[DATABASE]", "[DOCUMENT]", "[ANY_PATH]");
client.listCollectionIds({parent: formattedParent}).then(function(responses) {
var resources = responses[0];
for (var i = 0; i < resources.length; ++i) {
// doThingsWith(resources[i])
}
})
.catch(function(err) {
console.error(err);
});
It seems like they have added a method called getCollections() to Node.js:
firestore.doc(`/myCollection/myDocument`).getCollections().then(collections => {
for (let collection of collections) {
console.log(`Found collection with id: ${collection.id}`);
}
});
This example prints out all subcollections of the document at /myCollection/myDocument
Isn't this detailed in the documentation?
/**
* Delete a collection, in batches of batchSize. Note that this does
* not recursively delete subcollections of documents in the collection
*/
function deleteCollection(db, collectionRef, batchSize) {
var query = collectionRef.orderBy('__name__').limit(batchSize);
return new Promise(function(resolve, reject) {
deleteQueryBatch(db, query, batchSize, resolve, reject);
});
}
function deleteQueryBatch(db, query, batchSize, resolve, reject) {
query.get()
.then((snapshot) => {
// When there are no documents left, we are done
if (snapshot.size == 0) {
return 0;
}
// Delete documents in a batch
var batch = db.batch();
snapshot.docs.forEach(function(doc) {
batch.delete(doc.ref);
});
return batch.commit().then(function() {
return snapshot.size;
});
}).then(function(numDeleted) {
if (numDeleted <= batchSize) {
resolve();
return;
}
// Recurse on the next process tick, to avoid
// exploding the stack.
process.nextTick(function() {
deleteQueryBatch(db, query, batchSize, resolve, reject);
});
})
.catch(reject);
}
This answer is in the docs
Sadly the docs aren't clear what you import.
Based on the docs, my code ended up looking like this:
import admin, { firestore } from 'firebase-admin'
let collections: string[] = null
const adminRef: firestore.DocumentReference<any> = admin.firestore().doc(path)
const collectionRefs: firestore.CollectionReference[] = await adminRef.listCollections()
collections = collectionRefs.map((collectionRef: firestore.CollectionReference) => collectionRef.id)
This is of course Node.js server side code. As per the docs, this cannot be done on the client.

Using MultipartFile in flutter to send many images with id foreach item

I am trying to send a list of images using the MultipartFile, the sending is done according to the id and the key of each image ...
the problem, I am told that:
Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'int'
But it's not clear since I don't use any int in my songs ...
Here's my code:
sendPostImages(List responseImages, List userImages) async {
final _path = "files/send";
final uri = Uri.https("$myImgPath", _path);
final imageUploadRequest = http.MultipartRequest('POST', uri);
List imgs = [];
var filePostImg;
for (final item in responseImages) {
imgs.add({
...responseImages[item],
"name": "f$item",
});
filePostImg =
await http.MultipartFile.fromPath("f$item", userImages[item].path);
final listPostImgs =
await http.MultipartFile.fromPath("files", imgs.toString());
imageUploadRequest.files.add(filePostImg);
imageUploadRequest.files.add(listPostImgs);
try {
final streamedResponse = await imageUploadRequest.send();
final response = await http.Response.fromStream(streamedResponse);
if (response.statusCode != 200) {
final Map<String, dynamic> responseData = jsonDecode(response.body);
print('''
erreur de l'envoi des images...
$responseData
''');
}
final Map<String, dynamic> responseData = jsonDecode(response.body);
print(
'''
$responseData
''',
);
} catch (e) {
print(e);
}
}
}
The API Doc:
// When sending several files
"files": ["Object[]", [
// For each file
{
"fid": "String",
"fkey": "String",
"name": "String" // Custom name that you choose
}
]],
// For each file
"f01": "File" // The field's name must be the same as in the "files" object
},

How to parse this JSON Array in Flutter?

I am working with Flutter and am currently trying to create a graph. I am looking to parse this JSON Array from the link below. My issue is that the information provided in the "prices" object, the values are all inside arrays themselves. I want to get those values and split them into an X and Y list but I have no idea how to accomplish this. I posted a snippet of the JSON data below.
https://api.coingecko.com/api/v3/coins/bitcoin/market_chartvs_currency=usd&days=1
I am only familiar with parsing data by creating a class and constructor. Then create a fromJSON(Map<String, dynamic> json) class and putting the data into a list, as shown in the code snippet below that I created from another URL with object values. How could I go about parsing this array JSON data into two list data?
CODE TO PARSE JSON
List<Coins> _coins = List<Coins>();
Future<List<Coins>> fetchCoins() async {
var url = 'URL';
var response = await http.get(url);
var coins = List<Coins>();
if (response.statusCode == 200) {
var coinsJSON = json.decode(response.body);
for (var coinJSON in coinsJSON) {
coins.add(Coins.fromJson(coinJSON));
}
}
return coins;
}
#override
void initState() {
fetchCoins().then((value) {
setState(() {
_coins.addAll(value);
});
});
super.initState();
}
class Coins{
String symbol;
String name;
Coins(this.symbol, this.name);
Coins.fromJson(Map<String, dynamic> json) {
symbol = json['symbol'];
name = json['name'];
JSON DATA SNIPPET
{
"prices":[
[
1566344769277,
10758.856131083012
],
[
1566345110646,
10747.91694691537
],
[
1566345345922,
10743.789313302059
],
]
}
EDIT: SOLVED WITH THE HELP OF #EJABU.
class HistoricalData {
List prices;
List<num> listX = [];
List<num> listY = [];
HistoricalData(this.prices,this.listX, this.listY);
HistoricalData.fromJson(Map<String, dynamic> json) {
prices = json['prices'];
for (var price in prices) {
listX.add(price[0]);
listY.add(price[1]);
}
}
You may try this...
New class Coins definition:
class Coins {
List<num> listX = [];
List<num> listY = [];
Coins(this.listX, this.listY);
Coins.fromJson(Map<String, dynamic> json) {
List<List<num>> prices = json['prices'];
for (var price in prices) {
listX.add(price[0]);
listY.add(price[1]);
}
}
}
Then later you can fetch it by these lines :
// Future<List<Coins>> fetchCoins() async { // Remove This
Future<Coins> fetchCoins() async {
var url = 'URL';
var response = await http.get(url);
// var coins = List<Coins>(); // Remove This
Coins coins;
if (response.statusCode == 200) {
var coinsJSON = json.decode(response.body);
// Remove This
// for (var coinJSON in coinsJSON) {
// coins.add(Coins.fromJson(coinJSON));
// }
//
coins = Coins.fromJSON(coinsJSON);
}
return coins;
}
Accessing Data in Widget
In Widgets , our expected variable resides as property inside Coins class.
For example, if you use FutureBuilder, you may use these lines:
child: FutureBuilder(
future: fetchCoins(),
builder: (_, __) {
return SomeChartWidget(
listX: coins.listX,
listY: coins.listY,
);
},
),
Generating Serializers automatically
I suggest you take a look at https://pub.dev/packages/json_serializable, which is a package that does the boilerplate code generation for you. Although it might me a bit overkill to add something like this to your code or your workflow, automatically generating serializers is very convenient.
Not that in order to have custom sub-classes, they need to provide serialization as well.
If you want to extend your knowledge even further, you can also have a look at https://pub.dev/packages/built_value and https://pub.dev/packages/built_value_generator

mongoose update array and add new element

I pretty sure this question was asked many items, however I cannot find an answer to my particular problem, which seems very but I just can't seem to get it working. I have a user model with cart schema array embedded in it. I am trying to add an object to an array and if it exists only update quantity and price, if it is doesn't add to an array. what happens with my code is that it adds a new item when array is empty, it updates the item's quantity and price but it doesn't want to add a new item. I read a bit a bout and as far as I understood I cannot use two different db methods in one request. I would appreciate any help on this, this is the first time I am actually using mongooose.
const CartItem = require('../models/cartModel');
const User = require('../models/userModel');
exports.addToCart = (req, res) => {
const cartItem = new CartItem.model(req.body);
const user = new User.model();
User.model
.findById(req.params.id)
.exec((err, docs) => {
if (err) res.sendStatus(404);
let cart = docs.cart;
if (cart.length == 0) {
docs.cart.push(cartItem);
}
let cart = docs.cart;
let isInCart = cart.filter((item) => {
console.log(item._id, req.body._id);
if (item._id == req.body._id) {
item.quantity += req.body.quantity;
item.price += req.body.price;
return true;
}
});
if (isInCart) {
console.log(cart.length)
} else {
cart.push(cartItem);
console.log(false);
}
docs.save(function (err, docs) {
if (err) return (err);
res.json(docs);
});
});
};
I actually managed to get it working like this
exports.addToCart = (req, res) => {
const cartItem = new Cart.model(req.body);
const user = new User.model();
User.model
.findById(req.params.id)
.exec((err, docs) => {
if (err) res.sendStatus(404);
let cart = docs.cart;
let isInCart = cart.some((item) => {
console.log(item._id, req.body._id);
if (item._id == req.body._id) {
item.quantity += req.body.quantity;
item.price += req.body.price;
return true;
}
});
if (!isInCart) {
console.log(cart.length)
cart.push(cartItem);
}
if (cart.length == 0) {
cart.push(cartItem);
}
docs.save(function (err, docs) {
if (err) return (err);
res.json(docs);
});
});
};
don't know if this is the right way to do it, but I can both add a new product into my array and update values of existing ones
Maybe your problem hava a simpler solution: check this page at the mongoose documentation: there is a compatibility issue with some versions of mongoDB and mongoose, maybe you need to edit your model code to look like this:
const mongoose = require("mongoose");
const CartSchema = new mongoose.Schema({
//your code here
}, { usePushEach: true });
module.exports = mongoose.model("Cart", CartSchema);
You can find more information here: https://github.com/Automattic/mongoose/issues/5924
Hope it helps.

Resources