Add array via Cloud Firestore REST API - google-cloud-firestore

I am trying to send data to FireStore form Airtable by using Firestore REST API, and I am stack with sending an array. I get the array as a string in Firestore. But the outcome should be with Housekeeping and Transportation tags as separate items of the array.
const createTagsArr = (arr) => { let r = []; arr.forEach(obj => r.push(obj.name)); return r}
for (let i = 0; i < query.records.length; i++) {
if (query.records[i].getCellValueAsString("approved")) {
let obj = {
"fullDescription": query.records[i].getCellValueAsString("fullDescription"),
"tags": createTagsArr(query.records[i].getCellValue("tags").filter(obj => obj.name)),
"id": query.records[i].getCellValueAsString("initialForm"),
}
arr.push(obj)
}
}
const pushData = async () => {
for (let i = 0; i < arr.length; i++) {
let data = {
fullDescription: { stringValue: arr[i].fullDescription },
tags: { arrayValue: {values: [{stringValue: JSON.stringify(arr[i].tags)}]} },
let response = await fetch(`https://firestore.googleapis.com/v1/projects/{project-name}/databases/(default)/documents/{coolection}/${arr[i].id}?updateMask.fieldPaths=fullDescription&updateMask.fieldPaths=tags`, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + token
},
body: JSON.stringify({ "fields": data })
})
console.log(response)
}
}
const init = async () => {
console.log(providersArr)
await pushData()
}
init()
If I remove JSON.stringify() from this line:
tags: { arrayValue: {values: [{stringValue: JSON.stringify(providersArr[i].tags)}]} }
I am getting bad request error.
I would appreciate any help. Thank you!

Each value of an array must have a key of stringValue. To be able to separate the values of arr[i].tags, you should first iterate your arr[i].tags, construct the object and push it in an array. See sample code below:
const pushData = async () => {
for (let i = 0; i < arr.length; i++) {
// Initiate an empty array.
let tags = [];
// Iterate the `arr[i].tags` to create an array of objects.
for (const tag of arr[i].tags) {
// Construct the object to be pushed in the initialized array.
tags.push({ stringValue: tag });
}
let data = {
fullDescription: { stringValue: arr[i].fullDescription },
// Use the created array here.
tags: { arrayValue: {values: tags} },
}
let response = await fetch(`https://firestore.googleapis.com/v1/projects/{project-name}/databases/(default)/documents/{collection}/${arr[i].id}?updateMask.fieldPaths=fullDescription&updateMask.fieldPaths=tags`, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + token
},
body: JSON.stringify({ "fields": data })
})
console.log(response)
}
}
The code above will result to:
For more information, you may check out these documentation:
Value
ArrayValue

Related

Req. query doesn't pass

I'm trying to pull data from a document containing a logged-in user from the MongoDB database. However, req. the query doesn't seem to pass.
case "GET": {
const { userName } = req.query;
const users = await db
.collection("USERS")
.find({ user: { $in: [userName] } })
.toArray();
res.json(users);
break;
}
export async function getStaticProps() {
const res = await fetch(`http://localhost:3000/api/usersAPI`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
let users = await res.json();
return {
props: { users },
};
}

How to implement a PUT request in Vue 3

I am trying to implement a PUT request to the https://crudcrud.com/ REST API.
I have a list of users and when I click an update button, I would like to show a modal and allow the user to update any of the fields (name, email, image URL). The main concern is that I am struggling with how to format the PUT request.
This is my current solution
// template (UserCrud.vue)
<button #click="update(user._id)">Update</button>
// script
components: { Create },
setup() {
const state = reactive({
users: [],
})
onMounted(async () => {
const { data } = await axios.get(`/users`)
state.users = data
})
async function update(id) {
await axios.put(`/users/${id}`)
state.users = ???
}
return { state, destroy, addUser }
Here is some sample data:
[
{
"_id": "6012303e37711c03e87363b7",
"name": "Tyler Morales",
"email": "moratyle#gmail.com",
"avatar": "HTTP://linkURL.com
},
]
For reference, this is how I create a new user using the POST method:
export default {
components: { Modal },
emits: ['new-user-added'],
setup(_, { emit }) {
const isModalOpen = ref(false)
const state = reactive({
form: {
name: '',
email: '',
avatar: '',
},
})
async function submit() {
const { data } = await axios.post('/users', state.form)
emit('new-user-added', data)
state.form.email = ''
state.form.name = ''
state.form.avatar = ''
isModalOpen.value = false
}
return { isModalOpen, submit, state }
},
}
Check this repo for the complete repo: the files are UserCrud.vue & Create.vue
You should pass the user object as parameter then send it as body for the put request by setting the id as param :
<button #click="update(user)">Update</button>
...
async function update(user) {
let _user={...user,name:'Malik'};//example
await axios.put(`/users/${user._id}`,_user);
const { data } = await axios.get(`/users`)
state.users = data
}
You could use the same code of adding new user for the update by defining a property called editMode which has true in update mode and based on this property you could perform the right request
export default {
components: { Modal },
emits: ['new-user-added','user-edited'],
props:['editMode','user'],
setup(props, { emit }) {
const isModalOpen = ref(false)
const state = reactive({
form: {
name: '',
email: '',
avatar: '',
},
})
onMounted(()=>{
state.form=props.user;//user to edit
})
async function submit() {
if(props.editMode){
const { data } = await axios.put('/users/'+props.user._id, state.form)
emit('user-edited', data)
}else{
const { data } = await axios.post('/users', state.form)
emit('new-user-added', data)
state.form.email = ''
state.form.name = ''
state.form.avatar = ''
}
isModalOpen.value = false
}
return { isModalOpen, submit, state }
},
}

How to format axios GET call with nested params

I want to fetch an API
The call look like this;
const instance = axios.create({
method: 'GET',
uri: 'https://api.compound.finance/api/v2/account',
timeout: timeout,
params: {
block_number:'0',
page_number:'1',
page_size:'250',
max_health: {
value:'1'
},
},
headers: {
"Content-Type": "application/json",
},
});
The API spec https://compound.finance/docs/api
{
"addresses": [] // returns all accounts if empty or not included
"block_number": 0 // returns latest if given 0
"max_health": { "value": "10.0" }
"min_borrow_value_in_eth": { "value": "0.002" }
"page_number": 1
"page_size": 10
}
However the output URI contains some character to replace { } arround max_health value
The uri end up looking like this;
/api/v2/account?block_number=0&page_number=1&page_size=250&max_health=%7B%22value%22:%221%22%7D'
I have tried qs but it's not working as I expect.
I have tryed this to ;
let params = {
block_number:'0',
page_number:'1',
page_size:'250',
max_health: {
value:'1'
}
}
await instance.get('https://api.compound.finance/api/v2/account',JSON.stringify(params)).then( (response) => {...})
It gave me this error ;
TypeError: Cannot use 'in' operator to search for 'validateStatus' in
{"block_number":"0","page_number":"1","page_size":"250","max_health":{"value":"1"}}
Any help would be appreciated.
The fix;
Use paramSerializer
const instance = axios.create({
method: 'GET',
uri: 'https://api.compound.finance/api/v2/account',
timeout: timeout,
params: {
block_number:'0',
page_number:'1',
page_size:'250',
max_health: {
value:'1'
},
},
paramsSerializer: function (params) {
return Qs.stringify(params, {arrayFormat: 'brackets'})
},
headers: {
"Content-Type": "application/json",
},
});

Can't access Nested array object flutter

I have set of data, with some details,when i try to display the the one value returns null,other 2 data is fine,but if i try to show other data it's shows null,if i try to add that to setState,everything become null,There is no problem when i get the "Description","imagepath" i can show it, but the data from the replys object doesn't show
JSON
{
"doc": {
"image": {
"Description": "tested",
"replay": " ",
"Image_Rating": 0,
"replay_status": 0,
"Report_Date": "1591228800",
"Status": 1,
"_id": "5ed88ae73025a4445568ece3",
"image_path": "http://xxx.xxx.xxx.xxx:xxx/area_images/1670281356001.jpg",
"Created_User_Id": "5ed22c2507a33e2c1cf3a3a5",
"Branch_Id": "5ed22bf807a33e2c1cf3a3a4",
"image_temp_path": "http://xxx.xxx.xxx.xxx:xxx/area_images_temp/1670281356001.jpg",
"Order_Id": 32425,
"reg_date": "1591249638163",
"Area_Id": "5dc11c4046c214298f85e2e0",
"Section_Id": "5dc1097546c214298f85e2ae",
"Report_Time_Type": 1,
"mapperId": "5ed22c4207a33e2c1cf3a3a6",
"Created_At": "Thursday, June 4th, 2020, 11:17:18 AM",
"__v": 0
},
"replays": [
{
"replay": "Good\n",
"Report_Date": "1590796800",
"_id": "5ed248e0c1a47a3e8c4ce8bb"
}
]
}
}
Code
Future<String> getImageView(String imageid) async {
Future token = SharedPrefrence().getToken();
token.then((data) async {
var token = data;
var response = await http.post(Urls.Image_Details,
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer $token",
},
body: json.encode({
"imageId": imageid,
}));
if (response.statusCode == 200) {
try {
var resp = response.body;
Map<String, dynamic> value = json.decode(resp);
var name = value['doc']['image'];
Description = name["Description"].toString();
image_path = name["image_path"].toString();
replay = name["replays"]["replay"].toString();
setState(() {
Description = name["Description"].toString();
image_path = name["image_path"].toString();
// replay = name["replays"]["replay"].toString();
});
} catch (e) {
e.toString();
}
}
});
}
"replays" is an array. Try this: name["replays"][0]["replay"].toString()
By adding [0] it will get your first object from that array.
EDIT:
After looking at your json some more I see that name is the wrong object.
"replays" is a member of "doc" not of "image".
I think this should work:
replay = value['doc']["replays"][0]["replay"].toString();
The problem is
"replays": [
{
"replay": "Good\n",
"Report_Date": "1590796800",
"_id": "5ed248e0c1a47a3e8c4ce8bb"
}
]
This is a List of Maps. So as we access the first element in the list you should use
replay= value['doc']["replays"][0]["replay"].toString();
that is the zeroth element of the list.

Unable to update Data

Am trying to update the json data through an api call.
I was able to GET the data without any issues, as am not passing any Options in the request.
For UPDATE,
//saga.js
export function* BlurideaTitler(opt) {
const id = opt.id; // 4
const updatedTitle = opt.newTitle; // "title changed"
let options = {
crossDomain: true,
method: 'PUT',
json: true,
headers: {'Content-Type': 'application/json'},
body: {
title: updatedTitle
}
};
const requestURL = `http://localhost:3000/ideas/${id}`;
try {
yield call(request, requestURL, options);
} catch (err) {
console.log(err);
}
}
// request.js
export default function request(url, options) {
return fetch(url, options)
.then(checkStatus)
.then(parseJSON);
}
//db.json
JSON am trying to update.,
{
"ideas": [
{
"id": 4,
"title": "My fourth Idea",
"body": "Description of my fourth idea",
"created_date": "14-Apr-2019"
}
]
}
This is supposed to update the value of title. But it throws error'Bad request' . Can someone please let me know what am missing here.