What should I do to get the user's speed data at a specific time? Is it enough for me to subscribe to the recordClient API?
You can try to basic history session from Google Fit Git repository.
https://github.com/googlearchive/android-fit/blob/master/BasicHistorySessions/app/src/main/java/com/google/android/gms/fit/samples/basichistorysessions/MainActivity.java
// Build a session read request
SessionReadRequest readRequest = new SessionReadRequest.Builder()
.setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS)
.read(DataType.TYPE_SPEED)
.setSessionName(SAMPLE_SESSION_NAME)
.build();
// Invoke the Sessions API to fetch the session with the query and wait for the result
// of the read request.
SessionReadResult sessionReadResult =
Fitness.SessionsApi.readSession(mClient, readRequest)
.await(1, TimeUnit.MINUTES);
// Get a list of the sessions that match the criteria to check the result.
Log.i(TAG, "Session read was successful. Number of returned sessions is: "
+ sessionReadResult.getSessions().size());
for (Session session : sessionReadResult.getSessions()) {
// Process the session
dumpSession(session);
// Process the data sets for this session
List<DataSet> dataSets = sessionReadResult.getDataSet(session);
for (DataSet dataSet : dataSets) {
dumpDataSet(dataSet);
}
}
For more inforation on session just check this link
https://developers.google.com/fit/android/using-sessions#read_fitness_data_using_sessions
Related
My Code.gs has following function to filter data according to the username.
Sign in Function with Cache.put
function signin(obj){
...
....
**var Cache = CacheService.getScriptCache();
Cache.put('username',f[4])**
output = true
}
})
return output
}
**
Spreadsheet data as per column name**
`
function getByName(user, colName = 'userid') {
...........
Next data filter as per username (Cache.get)
`
function getFilteredData() {
**var Cache = CacheService.getScriptCache();**
var username = Cache.get('username')
var values = getByName(username)
Logger.log(username)
return values
}
I used getScriptCache as above functions
1.When I signed in from first account, I get correct filtered data
2.When I signed in from second account, I get data filtered as in First account. When I refresh and logged in to second account, I get correct filtered data as per second username. What I missed here?`
I am a developer working on integrating Google Fit with a smart wearable companion app.I am exporting steps data to google fit app.It works most of the time, but randomly sometimes it doesn't work.All hourly data has been dumped into DataSet class and inserting dataset in Fitness.getHistoryClient function. DataSet object had steps for the hours and I got 200 response for the API but the data is not seen in Google Fit app.
Could someone help me?
Here is my code,
val dataSource = DataSource.Builder()
.setAppPackageName(context)
.setDataType(DataType.TYPE_STEP_COUNT_DELTA)
.setStreamName(TAG + AppConstants.STEPSCOUNT_FIT.value)
.setType(DataSource.TYPE_RAW)
.build()
// Create a data set
var dataSet = DataSet.create(dataSource)
dataSet = fillStepsData(dataSet)
LogHelper.i(TAG, "Inserting the dataset in the History API.")
val lastSignedInAccount = GoogleSignIn.getLastSignedInAccount(context)
return if (lastSignedInAccount != null) {
Fitness.getHistoryClient(context, lastSignedInAccount)
.insertData(dataSet)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
// At this point, the data has been inserted and can be read.
LogHelper.i(TAG, "Data insert was successful!")
readHistoryData()
} else {
LogHelper.e(
TAG,
"There was a problem inserting the dataset.",
task.exception
)
}
}
}
fillStepsData(dataSet) - this function returns DataSet.DataSet contains DataPoint which includes all hourly data.
I have spent the last hour trying to look for a solution to rate limit my api.
I want to limit a path /users for example. But most rate limits work on 1 rate limit for everyone. I want to use api keys that can be generated by a user. People can generate free api let's say 1000 requests per day. Then if they pay some money they can get 5000 requests per day.
I would like to store these api keys in a mysql database.
Does anyone have any solution for this?
One way to structure your project would be:
user_keys table, includes the api key, the user, time of creation and number of uses so far.
When a user tries to generate a key, check that one doesn't exist yet, and add it to the DB.
When a request arrives, check if the key exists, if it does, do the following:
1: if it has been 24 hours since creation date, set number of uses to 0
2: increment the uses count
if you find the API key and it's at 1k the user reached his limit.
This is a basic implementation, and isn't very efficient, you'll want to cache the API keys in memory, either just in a hashmap in nodejs or using memcached/redis. But, get it working first before trying to optimize it.
EDIT: some code examples
//overly simple in memory cache
const apiKeys = {}
//one day's worth in milliseconds, used later on
const oneDayTime = 1000 * 60 * 60 * 24
//function to generate new API keys
function generateKey(user) {
if (apiKeys[user]) {
throw Error("user already has a key")
}
let key = makeRandomHash(); // just some function that creates a random string like "H#4/&DA23#$X/"
//share object so it can be reached by either key or user
//terrible idea, but when you save this in mysql you can just do a normal search query
apiKeys[user] = {
key: key,
user: user,
checked: Date.Now(),
uses: 0
}
apiKeys[key] = apiKeys[user]
}
// a function that does all the key verification for us
function isValid(key) {
//check if key even exists first
if (!apiKeys[key]) throw Error("invalid key")
//if it's been a whole day since it was last checked, reset its uses
if (Date.now() - apiKeys[key].checked >= oneDayTime) {
apiKeys[key].uses = 0
apiKeys[key].checked = Date.now()
}
//check if the user limit cap is reached
if (apiKeys[key].uses >= 1000) throw error("User daily qouta reached");
//increment the user's count and exit the function without errors
apiKeys[key].uses++;
}
//express middleware function
function limiter(req, res, next) {
try {
// get the API key, can be anywhere, part of json or in the header or even get query
let key = req.body["api_key"]
// if key is not valid, it will error out
isValid(key)
// pass on to the next function if there were no errors
next()
} catch (e) {
req.send(e)
}
}
this is an overly simplified implementation of a simpler idea, but I hope it gets the idea across.
the main thing you want to change here is how the API keys are saved and retrieved
I am trying to automate API requests using postman. So first in POST request I wrote a test to store all created IDs in Environment : Which is passing correct.
var jsondata = JSON.parse(responseBody);
tests["Status code is 201"] = responseCode.code === 201;
postman.setEnvironmentVariable("BrandID", jsondata.brand_id);
Then in Delete request I call my Environment in my url like /{{BrandID}} but it is deleting only the last record. So my guess is that environment is keeping only the last ID? What must I do to keep all IDs?
Each time you call your POST request, you overwrite your environment variable
So you can only delete the last one.
In order to process multiple ids, you shall build an array by adding new id at each call
You may proceed as follows in your POST request
my_array = postman.getEnvironmentVariable("BrandID");
if (my_array === undefined) // first time
{
postman.setEnvironmentVariable("BrandID", jsondata.brand_id); // creates your env var with first brand id
}
else
{
postman.setEnvironmentVariable("BrandID", array + "," + jsondata.brand_id); // updates your env var with next brand id
}
You should end up having an environment variable like BrandId = "brand_id1, brand_id2, etc..."
Then when you delete it, you delete the complete array (but that depends on your delete API)
I guess there may be cleaner ways to do so, but I'm not an expert in Postman nor Javascript, though that should work (at least for the environment variable creation).
Alexandre
I'm using Passport, Nodemailer, Sequelize, and Express to handle verification of user accounts who have signed up via email to the app.
To test this feature, I use Mailinator accounts to sign up, and send the email (along with a query string containing the user email and a uniquely-determined verification code) to the specified Mailinator address using Nodemailer. I then open the email in Nodemailer, click on the verification link, which updates the verification flag in the database and verifies the user.
This process works as I expect it to for exactly one user who signs up via email. When a second user signs up, the verification email is sent just as before with the username and unique verification codes in the query string, but this time, multiple users are being returned from the User.findAll query through Sequelize when the link is clicked. My query is intended to findAll possible matches of both email addresses and verification codes (since each user can only sign on with one email address and verification codes are unique), but for some reason the query is returning all matches from that query.
Here is some code for reference:
/* Sending the emails */
emails.sendActivationEmail = function(user){
const qso = {username: user.username, activationCode: user.activationCode};
const qs = querystring.stringify(qso);
const from = new helper.Email(<myEmailAddress#email.com>);
const to = new helper.Email(user.username);
const subject = 'Welcome to My Site!';
const content = new helper.Content('text/html', "<p> Thanks for signing up " +
"for our psych study, please <a href=\"http://localhost:7000/users/validate/account?" +
qs + "\">confirm your email</a></p>");
const mail = new helper.Mail(from, subject, to, content);
sendMail(mail); //invokes SendGrid mail helper function
}
/* Function invoked when user clicks on verification link in email */
emails.validateUserAccount = function(req, res){
const url = parseUrl(req.url);
const query = querystring.parse(url.query);
db.User.findAll({where: query}).then(function(matches){
if(matches.length !== 1){
res.send('error: multiple users found');
}
else{
db.User.update({
isVerified : true
},
{
where: {
username: matches[0].username
}
});
req.session.user = matches[0];
res.redirect('/');
}
}).catch(function(err){
console.error(err);
res.send(err);
});
}
Console statements in the validateUserAccount() function reveal that the query is exactly as I expect ({username: <emailAddress>, activationCode: <uniqueCode>}). However, console.log statements made in the first line after the findAll query is executed reveal that all users are being returned from the query, which should be impossible if the WHERE query is being passed in correctly, which it looks like it is from the logged statements. Why is User.findAll returning incorrect results from my query?
The problem here is that you are using the return value of querystring.parse()
As denoted in the Node docs:
Note: The object returned by the querystring.parse() method does not prototypically extend from the JavaScript Object. This means that the typical Object methods such as obj.toString(), obj.hasOwnProperty(), and others are not defined and will not work.
It's likely the where clause expects an actual JS Object.
Further, as #doublesharp mentioned, you probably want to be fetching one row and validating it, as opposed to findAlling the rows and then filtering through. Also, you should take advantage of callbacks. You're writing blocking code right now.