Query Firestore Rest API by multiple document ids - rest

I have noticed that documents that are returned by the API / runQuery do contain the document name, but I can't find any information within the structuredQuery docs how to query by multiple ids.
{
document: {
name: 'projects/:projectId/databases/(default)/documents/collection/id',
fields: ...,
createTime: '2021-01-16T13:35:02.151442Z',
updateTime: '2021-01-18T10:42:32.257199Z'
},
readTime: '2021-01-18T17:10:33.600112Z'
},
Firestore does support a whereIn query by document id Collection.where(firestore.FieldPath.documentId(), 'in', ["123","456","789"]), so I thought the Rest API might support is as well.
Do I miss something, or does runQuery not support queryById functionality?

This can be done by calling batchGet endpoint:
https://content-firestore.googleapis.com/v1beta1/projects/<PROJECT_ID>/databases/(default)/documents:batchGet
with the following JSON on the request body.
{
"documents": [
"projects/<PROJECT_ID>/databases/(default)/documents/<COLLECTION_ID>/<DOC_ID1>",
"projects/<PROJECT_ID>/databases/(default)/documents/<COLLECTION_ID>/<DOC_ID2>",
"projects/<PROJECT_ID>/databases/(default)/documents/<COLLECTION_ID>/<DOC_ID3>",
]
}

Related

Firestore Error: Unable to create document inside a nested collection with REST API

My firestore DB structure: 2020/abhishek/friend-requests/ where 2020 is a collection, abhishek is a document and friend-requests is a collection inside the document.
What am I trying to do?
I'm trying to create a new document inside friend-requests using REST API.
What I did so far?
I made a POST request to this endpoint:
https://firestore.googleapis.com/v1/projects/fuze-eee88/databases/(default)/documents/2020/abhishek/friend-requests/?documentId=newdocument
Request body:
{
"fields": {
"status": {
"booleanValue":"true"
}
}
}
The error I get:
{
"error": {
"code": 400,
"message": "Document parent name \"projects/fuze-eee88/databases/(default)/documents/2020//abhishek\" lacks a resource id at index 55.",
"status": "INVALID_ARGUMENT"
}
}
Seems you are getting that error because the document with the ID newdocument already exists in your Firestore database.You have to choose a unique ID for every new document that you add to Firestore database. You may try using a different ID, such as newdocument1 instead of new document.
You can have a look at below sample url
https://firestore.googleapis.com/v1/projects/<YOUR_PROJECT_ID>/databases/(default)/documents/<YOUR_COLLECTION_NAME>/<YOUR_DOCUMENT_ID>/<YOUR_SUBCOLLECTION_NAME>/?documentId=<YOUR_UNIQUE_ID>
After editing the above url as per your configuration will become:
https://firestore.googleapis.com/v1/projects/fuze-eee88/databases/(default)/documents/2020/abhishek/friend-requests/?documentId=newdocument1

CloudKit Bad Request on Users Record Update with Web Services API

I added a custom field to the default Users record type in CloudKit, and I'm trying to push a value to that new field.
Here's how my request is structured in Node JS:
var query = {
operations :[{
operationType: 'forceUpdate',
record:{
recordType: 'Users',
fields:{
myCustomField: { value: 'stuff' }
},
recordName: '_abc123'
}
}]
}
I'm getting this response from CloudKit:
records: [{
recordName: '_abc123',
reason: 'invalid id string, id=_abc123',
serverErrorCode: 'BAD_REQUEST'
}]
If I put that same custom field on another, custom Record Type (like if I make my own User (without the "s") type) that also has myCustomField on it, the update works fine. So there must be something special I have to do to update the system Users type.
Does anyone know how to update a field on a Users record with the web services API?

Custom filters that accept objects - lighthouse-php

I am using lighthouse-php as Api Gateway in a micro services architecture.
So for all my types I make a request internally through Guzzle.
But I am needing to implement filters that are suitable for any type and that give flexibility when making queries.
I need to implement a query like this:
query news (
order_by: {publication_date: desc}
where: {
_or: {categories_id: { _eq: 1 }, title: { _ilike: "news" } }
}
limit: 10
offset: 20
) {
id
category_name: name
photo
publication_date
text
title
}
But I have no idea how to implement this "where" filter that receives a composite object as in this example.
Remember that this query will not use any model within lumen, since it will be a custom query that will make a request to the microservice of news.
What I need is the way that my query receives whatever comes in where, limit and order, to send it on request. But I have no idea how to build something like this in the scheme.
Anyone have any idea how to do it?
Thanks friends.
Yes, you can.
Just now I'm making an component that will receive criterias to filter in graphql query so I need to fill filter's where params with those criterias.
Imagine the following schema:
type News{
id: ID!
title: String!
views: Int!
}
type Query{
getNews(where: _ #whereConditions(columns:["title", "views"])) : [News!] #all
}
We can make a query and fill where variables later
query GetNews($whereNews: [GetNewsWhereWhereConditions!]){
getNews(where: {OR: $whereNews}){
title
views
}
}
When querying we can fill the variables sending an object like
{
"where":[
{"column": "TITLE", "operator": "LIKE", "value": "Amazing title"},
{"column": "VIEWS", "operator": "GTE", "value": 10,
]
}

Should I include URLs or Ids of resources in REST API response?

I am designing a REST API. There's an entity Organization which may have a parent organization and multiple child organizations.
Let's say a user does request GET /organizations/1234.
What should I respond with?
I can use URLs to these other organizations.
{
"data": {
"name": "Microsoft",
"parent_organization": "http://api.myapi.asdfghj/organizations/1220",
"child_organizations": [
"http://api.myapi.asdfghj/organizations/1236",
"http://api.myapi.asdfghj/organizations/1214"
]
}
}
or I can use their ids
{
"data": {
"name": "Microsoft",
"parent_organization": 1220,
"child_organizations": [
1236,
1214
]
}
}
Which one is better?
If it's the one with full URLs, how do I do document that in swagger? Do I just set that as a string, something like the following?
definitions:
Organization:
type: object
properties:
data:
type: object
properties:
name:
type: string
parent_organization:
type: string
format: url
child_organizations:
type: array
items:
type: string
format: url
What about POST /organizations for creating a new user? Should the user specify parent and children as urls too?
I suggest you use urls rather than some ids. The advantage of having actual urls is that you can change them dynamically without worrying about the clients who depend on some base urls and then have to compute the actual urls from ids, etc.
For documentation purpose you can treat urls as strings and explain them like other params.

Rest API get resource id by field

What is a correct rest way of getting a resource ID by a field, for example a name. Take a look at the following operations:
GET /users/mike-thomas
GET /users/rick-astley
I don't want to use these operations at my API end, instead I want to write an API operation that will get me the ID when submitting a field (name in the case of users) for example:
GET /users/id-by-field
Submitted data:
{
"fullName": "Mike Thomas"
}
Return data:
{
"data": {
"id": "123456789012345678901234"
}
}
What you want is known as an algorithmic URL where the parameters for the algorithm are passed as URL parameters:
GET /users?name="Mike Thomas"
Advantages are that you are using the "root" resource (users) and the search parameters are easily extended without having to change anything in the routing. For example:
GET /users?text="Mike"&year=1962&gender=M
where text would be searched for in more than just the name.
The resultant data would be a list of users and could return more than the identification of those users. Unless fullName uniquely identifies users, that is what you need to allow for anyway. And of course the list could contain a single user if the parameters uniquely identified that user.
{
users: [
{
id: "123456789012345678901234",
fullName: "Mike Thomas",
dateJoined: 19620228
}
, {
id: "234567890123456789012345"
fullName: "Rick Astley",
dateJoined: 19620227
}
]
}