Limit depth of data returned - firebase

Is it possible to limit the depth of data returned from Firebase database?
For example, if I want to get some data from a parent object without waiting for all of its children & sub-children, can I specify that I only want x levels of objects?

Firebase does not yet have this capability.
We do intend to add it, but don't have a timetable yet.

There appears to be a shallow option...
{
"message": {
"user": {
"name": "Chris"
},
"body": "Hello!"
}
}
// A request to /message.json?shallow=true
// would return the following:
{
"user": true,
"body": true
}
// A request to /message/body.json?shallow=true
// would simply return:
"Hello!"
From: https://firebase.google.com/docs/database/rest/retrieve-data

Related

pushsubscription gives options instead of keys when using requestSubscription()

I'm trying to follow this tutorial to enable push notifications in my PWA. According to the tutorial, I should get a pushSubscription object like this:
{
"endpoint": "https://fcm.googleapis.com/fcm/send/cbx2QC6AGbY:APA91bEjTzUxaBU7j-YN7ReiXV-MD-bmk2pGsp9ZVq4Jj0yuBOhFRrUS9pjz5FMnIvUenVqNpALTh5Hng7HRQpcUNQMFblTLTF7aw-yu1dGqhBOJ-U3IBfnw3hz9hq-TJ4K5f9fHLvjY",
"expirationTime": null,
"keys": {
"p256dh": "BOXYnlKnMkzlMc6xlIjD8OmqVh-YqswZdut2M7zoAspl1UkFeQgSLYZ7eKqKcx6xMsGK7aAguQbcG9FMmlDrDIA=",
"auth": "if-YFywyb4g-bFB1hO9WMw=="
}
}
However when I inspect my subscription object I get something in the form of
{
"endpoint": "https://fcm.googleapis.com/fcm/send/cbx2QC6AGbY:APA91bEjTzUxaBU7j-YN7ReiXV-MD-bmk2pGsp9ZVq4Jj0yuBOhFRrUS9pjz5FMnIvUenVqNpALTh5Hng7HRQpcUNQMFblTLTF7aw-yu1dGqhBOJ-U3IBfnw3hz9hq-TJ4K5f9fHLvjY",
"expirationTime": null,
"options": {
"applicationServerKey": ArrayBuffer(65),
"userVisibleOnly": true
}
}
note that I do not get the keys object and instead get an options object.
Have the properties of the pushSubscription object changed? If I use this to send notifications, will it still work?
When saving my pushSubscription object with Mongoose, I used keys instead of options
If I then inspect the object in my db (on MLab in my case) it looks like
{
"endpoint": "https://fcm.googleapis.com/fcm/send/cbx2QC6AGbY:APA91bEjTzUxaBU7j-YN7ReiXV-MD-bmk2pGsp9ZVq4Jj0yuBOhFRrUS9pjz5FMnIvUenVqNpALTh5Hng7HRQpcUNQMFblTLTF7aw-yu1dGqhBOJ-U3IBfnw3hz9hq-TJ4K5f9fHLvjY",
"expirationTime": null,
"keys": {
"p256dh": "BOXYnlKnMkzlMc6xlIjD8OmqVh-YqswZdut2M7zoAspl1UkFeQgSLYZ7eKqKcx6xMsGK7aAguQbcG9FMmlDrDIA=",
"auth": "if-YFywyb4g-bFB1hO9WMw=="
}
}
I guess that the object in my console is visualized differently, thus showing me the options parameter instead of keys.

How can document references be used for Firestore API's [runQuery.startAt]?

When using the Firestore REST API to order and filter results, I am unable to use a cursor/reference value for the startAt value. I feel this may be possible, seeing it is provided in examples of Firestore's cursor-based pagination is detailed in their SDK: https://firebase.google.com/docs/firestore/query-data/query-cursors
I have a query that uses orderBy on a integer field within a document. I can successfully start at a specific integer value for this query, like so:
"structuredQuery": {
"from": [
{
"collectionId": "objects"
}
],
"orderBy": [
{
"field": {
"fieldPath": "counter"
},
"direction": "DESCENDING"
}
],
"startAt": {
"values": [
{
"integerValue": 15
}
]
}
}
I'm hoping to benefit from cursor pagination, but unfortunately if I change the startAt value to referenceValue, the query results do not reflect this, even though the query is successfully performed.
"startAt": {
"values": [
{
"referenceValue": "projects/.../databases/(default)/documents/objects/OjvmBvvQ9TkyyQiJ4ExJ"
}
]
}
Am I missing something in the way this works differently to the SDK examples?
Note that it's not a document reference but a document snapshot that you can use as a query cursor. A snapshot includes the field values needed for startAt. The SDKs take a document snapshot, extract the field values, and pass those values to startAt.
You can see the Node.js client library doing this here in createCursor and extractFieldValues.

Storing data on Firebase to be queried later

We have an application that will store data on Firebase (database) that will then be queried later.
What is the correct format to store the data in.
The example data will be completedGames. They will have data such as:
UserId
TimeToComplete
GameData
Etc...
The query later will then look for all completed games by UserId. We want to ensure the data is collected in the best way possible to query later, rather than refactoring later.
In your case, first off - be sure you have a good reason to use Firebase over Firestore. Once you're confident you should stick with Firebase Realtime Database, look at the below excerpt of documentation. So, you might actually have 2 separate parent nodes, 1 for userId and another for games. Each game node's child is a particular game, which has a child tree of game users (by userId).
Flatten data
structures
If the data is instead split into separate paths, also called
denormalization, it can be efficiently downloaded in separate calls,
as it is needed. Consider this flattened structure:
{
// 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": { ... }
}
}

Pass Alexa Skill slot name to a new intent on emit

When triggering one intent from another, such as
'LaunchRequest': function () {
this.emit('MyCustomIntent')
}
The request object passed to MyCustomIntent is
"request": {
type: 'LaunchRequest',
requestId: '...',
timestamp: '...',
locale: 'en-US'
}
Notice that no intent nor slot information is passed to MyCustomIntent.
However, every MyCustomIntent request that is sent by the Alexa will include
"request": {
"type": "IntentRequest",
...,
"intent": {
"name": "MyCustomIntent",
"slots": {
"MyCustomSlot": {
"name": "MyCustomSlot"
}
}
}
}
This creates a schism in the development process. When attempting to use MyCustomSlot within MyCustomIntent, if intent, intent.slots, and each respective intent.slots.MyCustomSlotdoes not exist, I will then have to use some default value to allow my code to function properly.
This means it will now be necessary for me to maintain my intent schema in both my Interaction Model, and within my Lambda Function. That sounds very messy, and could get out hand quickly when multiple slots and intents are introduced.
My Question
Is there any way to send the default slot values into the emit, so that I know, without a doubt, that I can always guarantee the same basic request object within MyCustomIntent?
You can use session attribute to pass slot values like
'firstIntent': function() {
this.attributes['slot_value1']= value;
alexa.emit('secondIntent');
}

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": { ... }
}
}

Resources