IN query in cloud firestore - firebase

Can I query multiple keywords in firestore? How I can match an array of keywords in firestore?
I have a collection of documents with a title, I want to query articles contains specific keywords.
Following is my document structure.
{
"users": {
"user_id_1": {
"username": "user one",
"profile_pic": "some_url",
"articles": {
"article_id_1": {
"title": "Firebase is so cool",
"comments": {
"comment_id_1": "First comment",
"comment_id_2": "I like trains"
}
},
"article_id_2": {
"title": "Firestore rocks!",
"comments": {
"comment_id_1": "SQL it's better",
"comment_id_2": "Do you know the wae?"
}
},
"article_id_3": {
"title": "Firestore awesome",
"comments": {
"comment_id_1": "SQL it's better",
"comment_id_2": "Do you know the wae?"
}
},
"article_id_4": {
"title": "Firestore is easy",
"comments": {
"comment_id_1": "SQL it's better",
"comment_id_2": "Do you know the wae?"
}
}
}
}
}
}
Here I want to search articles based on the following keywords.
["cool", "rocks", "Firestore is easy"]
I should get article_id_1, article_id_2 and article_id_4
Thanks.

This is not possible with Firestore alone. It's not a text search engine. You will want to export your data to a text search engine such as Algolia in order to perform text searches that are not based on simple text equality. The documentation suggests this solution.

Related

Dialogflow simulator not responding

I am testing a simple conversation from my dialogflow simulator using a fulfillment hosted in firebase functions.
And I am receiving the fulfillment response when triggered
But my simulator is showing this. Saying no response is received.
Please help
The complete RAW fulfillment response
{
"responseId": "99b660de-e2ca-4d8c-ace5-ef724fe5ee72",
"queryResult": {
"queryText": "male",
"parameters": {
"gender": "male"
},
"allRequiredParamsPresent": true,
"webhookPayload": {
"google": {
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "Amazing"
}
}
]
},
"expectUserResponse": true,
"userStorage": "{\"data\":{}}"
}
},
"outputContexts": [
{
"name": "projects/assurance-purple/agent/sessions/bf891cbe-8642-eb61-ed7b-d6796adfab60/contexts/_actions_on_google",
"lifespanCount": 99,
"parameters": {
"data": "{}",
"gender.original": "male",
"gender": "male"
}
}
],
"intent": {
"name": "projects/assurance-purple/agent/intents/96b523a0-7a3a-4135-bdfc-d9d8ad16b661",
"displayName": "getGender"
},
"intentDetectionConfidence": 1,
"diagnosticInfo": {
"webhook_latency_ms": 45
},
"languageCode": "en"
},
"webhookStatus": {
"message": "Webhook execution successful"
}
}
My actions on google Testing debug tab
`
{
"response": "We're sorry, but something went wrong. Please try again.",
"expectUserResponse": false,
"conversationToken": "",
"audioResponse": "",
"visualResponse": {
"visualElementsList": [
{
"displayText": {
"content": "Sorry, this action is not available in simulation"
}
}
],
"suggestionsList": [],
"agentLogoUrl": ""
},
"clientError": 4,
"is3pResponse": false
}
`
You don't show the entire response (copying and pasting it as text in your question would have been better), but it looks like you're sending a response back for an Action, but trying to test it in Dialogflow's conversation tool.
The Actions on Google response is slightly different than the response that Dialogflow expects to handle the additional features that the Assistant supports. Because of this, you need to use the Actions on Google simulator when testing your agent.
The Dialogflow test is looking for some specific fields to show the response that are not included with the actions-on-google library, and it will not show anything that is in a Google RichResponse object.
To summarize:
If you are working with an Action, use the Actions on Google simulator.
If you are working with other Dialogflow integrations, you can use the test tool on the right in Dialogflow.
Update
The error you're indicating from the AoG Simulator suggests that you're trying to just issue a statement in the conversation and not starting the Action, or that the Action has quit. Make sure you're talking to the action by starting it with "talk to my test app" or whatever the name of your Action is.

Can I insert data in Firebase database with multiple children?

Can I insert data into my Firebase database with multiples children? Can I have like this JSON example where there are 2 children of the phones?
{
"person1": {
"id": 12345,
"name": "John Doe",
"phones": {
"home": "800-123-4567",
"mobile": "877-123-1234"
}
}
}
Yeah, why not? You can write to database like these (For Android):-
mDatabase.child("person1").child("phones").child("home").setValue("800-123-4567");
mDatabase.child("person1").child("phones").child("mobile").setValue("877-123-1234");

Firebase database data aggregation

Let's take a look at "Instagram-like" app, as an example.
In the feed we got posts, with user avatar and name at the top, photo or video below, and last comments, likes count and post time at the bottom.
Basically, at the client I'm waiting to get from backend something like
{
username: "John",
avatar:"some_link",
photo:"photo_url",
likes:"9",
time:"182937428",
comments:[comments there]
}
but using Firebase, I need to store data in more flat way. so there will be "users", "posts" and "comments" in data JSON.
How am I suppose to aggregate data from those nodes in some kind of single object, which is easy to use at client?
Or should I ask Firebase for posts, than for all users in it, and for all their comments, and do aggregation after all three 'requests' are done?
You should implement "shallow" tree structure, and use references where needed.
That means that for most cases in your app you should use the object as at is, Making sure that it contain the "essential data" (in the example below "the chat title"), and keys for "further" information (in the example, keys to the "members").
from firebase docs (https://firebase.google.com/docs/database/web/structure-data):
bad
{
// This is a poorly nested data architecture, because iterating the children
// of the "chats" node to get a list of conversation titles requires
// potentially downloading hundreds of megabytes of messages
"chats": {
"one": {
"title": "Historical Tech Pioneers",
"messages": {
"m1": { "sender": "ghopper", "message": "Relay malfunction found. Cause: moth." },
"m2": { ... },
// a very long list of messages
}
},
"two": { ... }
}
}
good
{
// Chats contains only meta info about each conversation
// stored under the chats's unique ID
"chats": {
"one": {
"title": "Historical Tech Pioneers",
"lastMessage": "ghopper: Relay malfunction found. Cause: moth.",
"timestamp": 1459361875666
},
"two": { ... },
"three": { ... }
},
// Conversation members are easily accessible
// and stored by chat conversation ID
"members": {
// we'll talk about indices like this below
"one": {
"ghopper": true,
"alovelace": true,
"eclarke": true
},
"two": { ... },
"three": { ... }
},
// Messages are separate from data we may want to iterate quickly
// but still easily paginated and queried, and organized by chat
// conversation ID
"messages": {
"one": {
"m1": {
"name": "eclarke",
"message": "The relay seems to be malfunctioning.",
"timestamp": 1459361875337
},
"m2": { ... },
"m3": { ... }
},
"two": { ... },
"three": { ... }
}
}

Firebase Rules for a Chat feature

In my project I have a chat feature to allow users to speak in private message. For now it's only one-to-one, but it could be improved later to allow group discussion.
Currently I'm struggling with custom rules. Indeed, for my projet I need users to have theirs own list of discussion. For example, user A and B talk through private message, but user C, D or whatever shouldn't be able to read the discussion.
Here is how the Database json look like :
{
"room-messages": {
"-KWgoXt567vzgxZ-1gii": {
"-KWgoXt567vzgxZ-1gii": {
"name": "Friendly Chat",
"sent": 1479294463723,
"text": "Nice ! You have created a new chat",
"uid": "user_A_id"
},
"-KWh5_W12qsXFaJhyOvx": {
"name": "Lucien Guimaraes",
"sent": 1479294463728,
"text": "A text message",
"uid": "user_B_id"
}
},
"-KWgoXt567vzgxZ-1git": {
"-KWgoXt567vzgxZ-1git": {
"name": "Friendly Chat",
"sent": 1479294463723,
"text": "Nice ! You have created a new chat (2)",
"uid": "user_A_id"
},
"-KWh5_W12qsXFaJhyOvz": {
"name": "Lucien Guimaraes",
"sent": 1479294463729,
"text": "Test",
"uid": "user_C_id"
}
}
},
"room-metadata": {
"-KWgoXt567vzgxZ-1gii": {
"users": {
"user_A_id": "Lucien Guimaraes",
"user_B_id": "Geralt of Rivia"
}
},
"-KWgoXt567vzgxZ-1git": {
"users": {
"user_A_id": "Lucien Guimaraes",
"user_C_id": " Gordon Freeman"
}
}
}
}
For your information "user_A_id" or "user_B_id" should be the id provided by Firebase Authentication. In this example I want user A to get all rooms (because he's in both available room). User B should have only the first room and user B only the last room.
Here are my rules :
I have been able to allow write access for Rooms almost perfectly (the only remaining issue is user who can't delete a message, I don't know why). But for Read I have a huge issue : I can't set a custom rule because the value "$roomId" is unknown inside "room-messages". It's only possible to do this as a child of "$roomId".
Is there any solution for what I want implemented ?
Thanks !
#AskFirebase

Firebase data schema guidance

I am newbie to Firebase and working on to create events using firebase. Here i am inviting my friends using their phone number.(It is not necessary that whom i am inviting will be part of the system user.)
Below is my schema:
{
"events": [
{
"message": "Lunch",
"startTime": 1469471400000,
"eventCreatorId": 1,
"endTime": 1469471400000,
"invitees": [
{
"phone": "1234567890",
"type": "phone"
},
{
"phone": "345678901",
"type": "phone"
}
]
}
]
}
Now problem is that how i can find list of all events for specific invites?? (i.e in above case i want to find list of all events for user with phone number eqaul to 345678901.)
Can anyone suggest good schema to handle above scenario with firebase?
Welcome to using a NoSQL database. :-)
In NoSQL you often end up modeling the data different, to allow the queries that you want your app to execute. In this case, you apparently want to both show the invitees per event and the events per invitee. If that is the case, you'll store the data in both formats:
{
"events": {
"event1": {
"message": "Lunch",
"startTime": 1469471400000,
"eventCreatorId": 1,
"endTime": 1469471400000,
"invitees": {
"phone_1234567890": true,
"phone_345678901": true
}
}
},
"users": {
"phone_1234567890": {
"phone": "1234567890",
"type": "phone",
"events": {
"event1": true
}
},
"phone_345678901": {
"phone": "345678901",
"type": "phone"
"events": {
"event1": true
}
}
}
}
You'll see that I've split your data into two separate top-level nodes: events and users. They refer to each other with so-called explicit indexes, essentially a set of foreign keys that you manage (and join) in your client-side code.
I've also replaced you arrays with named keys. If your events/users have natural keys (such as uid for identifying the user if you happen to use Firebase Authentication) you'd use that for the key. But otherwise, you can use Firebase push ids. Using such keys leads to a more scalable data structure then depending on array indices.
Both of these topics are covered in the Firebase documentation on data structuring. I also highly recommend this article on NoSQL data modeling.

Resources