Need help with DynamoDB.
I am switching back end from Parse.com (because they are retiring parse) to AWS mobile hub.
I want to capture and save the date and time for which a row or item of data is written into my dynamodb table. In parse it is done automatically but not so in dynamodb.
I have searched around on the internet for clues but no solid explanation or example at the moment.
Can someone please point me in the right direction or pls show an example code here on how to implement CreatedAt and UpdatedAt into dynamodb.
Do I get my system time and save it to dynamodb or get server time?
If I need to get server timestamp which AWS server time do I get and how can I implement it?
Thanks a lot.
AWS enables one to Use AWS Lambda with Amazon DynamoDB
This enables you to trigger server-side code based on DynamoDB events. It's way more involved than Parse but would enable you to avoid using app-side dates/times/code to maintain CreatedAt and UpdatedAt values.
Such datetime values need to be Ints or Strings as Datetime is not a JSON type and DynamoDB doesn't go beyond basic JSON field types.
This is tricky for a number of reasons. First if you require strict order of events, then using time can cause a bunch of errors and you might want to look into more advanced distributed systems algorithms like https://en.wikipedia.org/wiki/Lamport_timestamps or https://en.wikipedia.org/wiki/Vector_clock.
If just 'pretty close' is fine for your use case then the main thing you need to keep in mind is that mobile device system time is often incorrect. User's can change the clock, move between time zones, ect... There are a few things you could do.
A) You could have your own server that keeps a central time that you ping
B) Dynamo also returns a date header when you make calls which you could look, but it's returned in the response. However you could at least use it to see if the date on your device is accurate. The SDK some something similar if you see https://github.com/aws/aws-sdk-android/blob/78cdf680115a891a6e1355c56068e2f56e3c5056/aws-android-sdk-core/src/main/java/com/amazonaws/http/AmazonHttpClient.java when Dynamo returns an error if the date in the signature from the request doesn't match the time Dynamo is expecting. This probably isn't the best solution, but should at least give you ideas of possible avenues.
I have decided to capture System.currentTimeMillis() at the time a user clicks the post/save button on my app and save the Epoch time in milliseconds into my DB CreatedAT attribute.
I read here : "One of the most important things to realize is that 2 persons calling System.currentTimeMillis() at the same time should get the same result no matter where they are one the planet" So I intend to generate a random UUID Primary Key (Hash Key) and then save the user's CreatedAT time as the Sort Key.
I am open to any other practical options. I will use this in the mean time for testing and observe the behaviour.
Related
I'm doing a query to fetch only 1 month old documents.
I store the creation time of the document itself
timestamp : 9 Apr, 2020 10:03:43 AM
Now, in my query , I want to get all the documents whithin the current month but I dont want to use currentDate from my client (so it cannot be changed) but also I dont want to query that document to find the timestamps of that document
Query
FirebaseFirestore.getInstance().collection("orders").whereEqualTo("shopId",shopId)
.whereEqualTo("status", 7).startAt().endAt().get().await()
I want to know an efficient server aproximation to set at .startAt().endAt() to query just the documents with status 7 in which has past 1 month
any ideas?
Firestore does not offer timeboxed queries that restrict a range of documents based on the sense of server time. You will have to trust that the client is sending the correct time.
The only control you have over time is using request.time in security rules. You could write a rule to allow queries that only fall within times based on the server timestamp, but it's still up to the client to specify the time correctly in the query. The rules will not be able to filter results based on time.
You might want to read more about how server timestamps work with security rules at the end of this article.
I am new to coding and I am just playing around to build an app where everyone can post new events. So I have already created notes like "user" and "events". The problem I face off is that I dont know how to avoid duplication like for example if two users are posting the excat same event.
I don't want to show them twice in my RecyclerView.
So I have to compare the date, the location and the description, due to this many queries, is the Firebase Realtimedatabase the right "tool"? Or should I use another software.
------/Events
---------/LbwXYVICCl9xd5m..
--------------datum: 10.04.2019
--------------userid: OncDIQis...
--------------location:New York
--------------description:Coldplay
You seem to define two events as being the same based on some of their properties having the same value. In a scenario like that, I'd use those combined properties as the key of the event.
So if you say that two events are the same if they have the same date, location, and description, then you can create the unique key of that event as ${date}_${location}_${description}. For example:
20190410_New York_Coldplay
I've put the date in an easier to search for format, which also filters the .s (since those are not allowed in keys. Now you can store the event under that key:
Events
20190410_New York_Coldplay
datum: 10.04.2019
userid: OncDIQis...
location:New York
description:Coldplay
With the above structure, if another user tries to create an equivalent event, it will get the same key.
Firebase Real-time database is the right tool for you as it updates the database in real time.
At the time of fetching the data from the firebase, you can check whether it is already present in your local database(where you are collecting data fetched from the firebase) or not.
I hope this will help you out.
I understand that one cannot do aggregation queries on firebase to compute statistics and/or return bucketed data similar to a relational db. I wondered if denormalising data could some how replicate aggregation?
I have the following specific problem:
I have a set of data with id, subject, score, author, date, tags, locations.
I would like to bucket the data in each of these dimensions according to some "similarity" rules e.g. all data on the same day bucketed together, all data located within 10 metres etc., each bucket showing me how many pieces of data in that bucket and the average score.
Once I choose a bucket, the underlying ids are retrieved.
Given a set of retrieved Ids, I download the data or go back to step 1 to refine using these ids.
I have gone through the Android documentation but cannot work out a way of doing this. Is something like this possible in Firebase? Is it possible via denormalisation or by uploading server code?
I am loathe to give up Firebase as it is so easy and simple to use but aggregation is a core part of my app so hope it is...
Thanks,
Riz
Edit: Edited to make problem clearer.
My app allows users to save a "guess" about something to a database on parse, but I want to cut off these guesses at a certain time, say for example 5:00 PM CST, and also prevent multiple submissions from the same person. Any advice on how to go about this?
You can create a beforeSave function in Cloud Code and reject any saves that are outside of your timespan.
https://www.parse.com/docs/js/guide#cloud-code-beforesave-triggers
We are building an android app that needs to synchronize phone contacts with people already registered on the app. We are using firebase
To do this, we'd like to retrieve a list of existing users based on their phone numbers.
I have managed to retrieve users based on their phone number with ref.orderByChild("phone").equalTo($phoneNumber)
But I am wondering if there is a way of passing a list of phone numbers, instead of querying for each phone number one at a time ?
Something like this:
ref.orderByChild("phone").isIn([phone1, phone2, phone3])
I am just beginning to learn Firebase but I love the concept :)
Thanks a lot for your answers!
Firebase doesn't have or or in operators on its queries.
The closest you can come with with the startAt and endAt functions, to select a range. But that doesn't work for your use-case.
Normally when people are asking for this type of operation, there is a relation between all the pieces that they're trying to combine in a query. For example in your case, the use-case is likely something like: "get the name for all contacts in the user's address book".
In such a situation there are a few options:
monitor each contact with a separate query
embed the necessary metadata for each contact into the user's address book
Option 2 is the cheapest way to get the information, because you only need to read the address book. But it comes at the cost of data duplication, which more relationally trained developers are unused to. See this answer for a coughgreatcough example of such denormalization: Firebase data structure and url
Option 1 is not nearly as expensive as you may expect, since Firebase will open a socket connection only once and then perform all additional queries over that same connection.