User.findOne() in a collection other than 'Users' - java

I wrote an app that has a logic for email verification and it's trigered when an user sign up. I use two Mongoose models: one to record the data from the users and other model for the authentication tokens. In the token schema I grab the user's ID.
In my User controller, when the app needs to authenticate the token that was prevously sent to the user, the token is identified and after that I must to find the user's ID that was recorded in the token schema in it's Mongo collection. For that, I have a User.findOne() function.
What I'm wanna do is to grab the _userId:ObjectId("some-userid-number") that is stored in the token collection, but I must to doi te inside the fuction, something like that
User.findOne({ _userID: mongoose.Schema.Types.ObjectId._userID, ref: 'Token' })
So, how can I grab the _userId stored as a ObjectId in the Token model?
Thanks a lot!

If the Mongoose models are defined with refs, findOne/findAll can join data from multiple collections using populate. Note that using populate will result in multiple queries being sent to mongodb.
Token
.findOne({ token })
.select("_userId")
.populate({
path: '_userId',
select: 'firstName', // Specify the necessary user properties
options: { lean: true }
})
.lean()
.exec();
The request can instead be formulated as an aggregation query if performance is important. This request will result in a single query being sent to mongodb.
Token
.aggregate([
{$match: {
token
}},
{$lookup: {
from: 'users', // the name of the user collection
localField: '_userId',
foreignField: '_id',
as: 'user'
}},
{$project: {
// Specify the necessary user properties in the projection
firstName: '$user.firstName'
}}
])
.exec()
Remember to create an index on Token(_userId)

The answer is simple than I imagine :-)
async confirmationPost (req, res) {
const token_ = req.body.token;
await Token.findOne({ token:token_ }, function (err, tokenData) {
if (!tokenData) {
return res.status(),
}
else
{
tokenUser = tokenData._userId
User.findOne({ _id: tokenUser }, function (err, user) {
// logic-logic
}
I was able to captura all the token colletion data, so was a simpla case of defining tha variable :-)

Related

Destructure a JsonObject to a GraphQL Type on Return

Vertx is a big fan of json being a first class citizen, and I'm a big fan of it as well. I have jsonb columns stored in postgres as my primary data storage mechanism. Kind of like this:
CREATE TABLE game (
id varchar(16) not null default next_id() primary key,
data jsonb not null
);
and I retrieve the data, work on the json object, and return it to the browser. Works great.
I'm trying to use GraphQL as well, though, but it seems that I can't convert a json object into the graphql type. e.g. i have this data stored in the db:
{"name": "dominion", "createdBy": "Donald X. Vaccarino", "id": 233}
and this is the graphql type:
type Game {
id: Long,
name: String,
createdBy: String,
createdAt: DateTime,
deletedAt: DateTime
}
and this graphql query returns a list of empty items because the jsonObject (game) within the jsonArray doesn't get desctructured into the Game type:
type Query {
allGames(secureOnly: Boolean = false): [Game]
}
but the list of games does show up if i use json for the query result type:
type Query {
allGames(secureOnly: Boolean = false): [JSON]
}
The problem with this, though, is that there is now no type information in the graphql schema. There's no way to let the client know what properties are in the JSON object
My data fetcher has this type:
DataFetcher[CompletionStage[JsonArray]]
Any thoughts on how I can return a json in code and have the graphql response return the game type?
The default GraphQL data fetcher is PropertyDataFetcher.
If you want to support Vert.x JsonObject and JsonArray, you must configure GraphQL-Java to use VertxPropertyDataFetcher instead:
RuntimeWiring.Builder builder = RuntimeWiring.newRuntimeWiring();
builder.wiringFactory(new WiringFactory() {
#Override
public DataFetcher<Object> getDefaultDataFetcher(FieldWiringEnvironment environment) {
return VertxPropertyDataFetcher.create(environment.getFieldDefinition().getName());
}
});

Complex queries in elasticsearch

Let's say we have a entity "Device" it contains other entity "DeviceInfo", and we have a entity "Site" which contains a List of "DeviceInfo" entities, and "DeviceInfo" has a "Device" and a "Site" in its properties.
My task was to find all "Device"s which are in one "Site". To some endpoint I would send a "Site" id and page number and size of page (since it has to be pageable). I have made it work by creating a JPA specification
public static Specification<Device> bySearchRequest(final DeviceSearchRequest searchRequest) {
return (root, query, cb) -> {
final Join<Device, DeviceInfo> deviceInfo
= root.join(Device_.deviceInfo, JoinType.LEFT);
final Join<DeviceInfo, Site> site
= deviceInfo.join(DeviceInfo_.site, JoinType.LEFT);
return cb.and(cb.equal(site.get(Site.id), searchRequest.getSiteId()));
};
}
And then using I would convert the "Device"s to "IndexDevice"s which is in ES.
deviceRepository.findAll(currentUser,
DeviceRepository.Specs.bySearchRequest(searchRequest),
new PageRequest(searchRequest.getPage(), searchRequest.getSize()))
.getContent().stream().map(x ->indexedDeviceConverter.convert(x)).collect(Collectors.toList());
That is it. It works. But here I am fetching the data from DB, and I already have everything in Elasticsearch. Is there a way to make this same query to fetch the data directly from ES (with paging) ?
Only difference is that in ES "IndexedDevice" has a direct relation with a "IndexedSite" (there is no "IndexedDeviceInfo").
IndexedDevice
{
"id":"3eba5104-0c7a-4564-8270-062945cc8f5e",
"name":"D4",
"site":{
"id":"46e7ada4-3f34-4962-b849-fac59c8fe8ad",
"name":"SomeSite",
"displayInformation":"SomeSite",
"subtitle":""
},
"suggest":{
"input":[]
},
"displayInformation":"D4",
"subtitle":""
}
IndexedSite
{
"id": "46e7ada4-3f34-4962-b849-fac59c8fe8ad",
"name": "SomeSite",
"displayInformation": "SomeSite",
"subtitle": ""
}
I managed to do it. At the end it was really simple. I used ElasticsearchRepository (org.springframework.data.elasticsearch.repository).
elasticsearchRepositoy.search(QueryBuilders.termsQuery
("site.id",
searchRequest.getSite()),
new PageRequest(searchRequest.getPage(),
searchRequest.getSize()));

How to exclude some fields when listing Grails domain?

I'm wondering how can I list Grails domain and exclude some fields at same time. I'm guessing solution must be simple but I just can not see it.
I prepared some example with domain User:
class User implements Serializable {
String username
String email
Date lastUpdated
String password
Integer status
static constraints = { }
static mapping = { }
}
At this point I want to list all users which have status below 2.
render User.findAllByStatusLessThen(2) as JSON
I want to render JSON response to clientside without some fields. For example I just want to render users with fields username and lastUpdated so rendered JSON would look like this:
[{"username": "user1", "lastUpdated":"2016-09-21 06:49:46"}, {"username": "user2", "lastUpdated":"2016-09-22 11:24:42"}]
What's the easiest way to achieve that?
Yeah.It's simple.Try below solutions
Solution 1
List userList = User.where{ status < 2 }.property("username").property("lastUpdated").list()
render userList as JSON
output
[{"user1", "2016-09-21 06:49:46"}, {"user2", "2016-09-22 11:24:42"}]
Solution 2 - using this you will get output in the Key-Value pair
List userList = User.findAllByStatusLessThen(2)?.collect{
[username : it.username, lastUpdated: it.lastUpdated]}
render userList as JSON
output
[{"username": "user1", "lastUpdated":"2016-09-21 06:49:46"}, {"username": "user2", "lastUpdated":"2016-09-22 11:24:42"}]
You are looking for Grails projections.
def result = Person.createCriteria().list {
lt("status", 2)
projections {
property('username')
property('lastUpdated')
}
} as JSON
Well if you want the result to be in key-value pair you can take advantage of HQL query
def query = """select new map(u.username as username, u.lastUpdated as lastUpdated) from User u where status < 2"""
def result = User.executeQuery(query)
println (result as JSON)
This will give you the output as below
[{"username": "user1", "lastUpdated":"2016-09-21 06:49:46"}, {"username": "user2", "lastUpdated":"2016-09-22 11:24:42"}]

How to save the response data return by Facebook in Java class using Spring MVC

I am trying to save the user data which is return by the Facebook response.
I am using Facebook Javascript.Response is in JSon format and I want to parse it first and then save it in to my database using java.
<script>
// This is called with the results from from FB.getLoginStatus().
function statusChangeCallback(response) {
console.log('statusChangeCallback');
console.log(response);
// The response object is returned with a status field that lets the
// app know the current login status of the person.
// Full docs on the response object can be found in the documentation
// for FB.getLoginStatus().
if (response.status === 'connected') {
// Logged into your app and Facebook.
/* var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
console.log("User id is" + uid);
console.log(accessToken); */
document.getElementById('accesstoken').value=response.authResponse.accessToken;
console.log(response.authResponse.accessToken);
testAPI();
} else if (response.status === 'not_authorized') {
// The person is logged into Facebook, but not your app.
document.getElementById('status').innerHTML = 'Please log ' +
'into this app.';
} else {
// The person is not logged into Facebook, so we're not sure if
// they are logged into this app or not.
document.getElementById('status').innerHTML = 'Please log ' +
'into Facebook.';
}
}
// This function is called when someone finishes with the Login
// Button. See the onlogin handler attached to it in the sample
// code below.
function checkLoginState() {
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
});
}
window.fbAsyncInit = function() {
FB.init({
appId : 'xxxxxxxxxxxxxxxxxxxx',
cookie : true, // enable cookies to allow the server to access
// the session
xfbml : true, // parse social plugins on this page
version : 'v2.2' // use version 2.2
});
// Now that we've initialized the JavaScript SDK, we call
// FB.getLoginStatus(). This function gets the state of the
// person visiting this page and can return one of three states to
// the callback you provide. They can be:
//
// 1. Logged into your app ('connected')
// 2. Logged into Facebook, but not your app ('not_authorized')
// 3. Not logged into Facebook and can't tell if they are logged into
// your app or not.
//
// These three cases are handled in the callback function.
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
});
};
// Load the SDK asynchronously
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
// Here we run a very simple test of the Graph API after login is
// successful. See statusChangeCallback() for when this call is made.
function testAPI() {
// window.location="http://localhost:8080/SpringMvcHibernateJavaBased/list";
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Successful login for: ' + response.name);
console.log(response);
document.getElementById('status').innerHTML =
'Thanks for logging in, ' + response.name + '!';
document.getElementById('usernamefb').value=response.name;
document.getElementById('userId').value=response.id;
document.getElementById('emailfb').value=response.email;
});
}
function checkLogoutState(){
FB.logout(function(response) {
FB.Auth.setAuthResponse(null, 'unknown');
});
};
function checkData()
{
return $.ajax({
})
}
</script>
I am using Spring MVC approach fully JAVA based not using any xml files.
I have searched lot but didn't get any solution
In "if (response.status === 'connected') {}" block you need to call another API of Facebook to fetch the user's details by passing user id and token and after receiving the data you can call your own controller through Ajax and save into DB if required.
Another solution can be, you may use "http://projects.spring.io/spring-social/" on server side itself.
Krish

How to use facebook api taggable_friends by Open Graph tag friend

How to use facebook api taggable_friends by Open Graph tag friend.
my app use taggable_friends api i want to tag my friend in friends wall.
to use Mentioning friends or Tagging friends
https://developers.facebook.com/docs/opengraph/using-actions/v2.0#capabilities
And I use Open Graph doc Step by Step to try
but give me "You, or this app's Open Graph Test User, must have published this action at least once" how to setting?
https://developers.facebook.com/docs/apps/review/opengraph
On FB javascript sdk,
-* fb dashboard -> Open Graph
Create a story
List item make sure you enable the 'capabilities' features such as -tags, -user messages, -place, etc. in your action type.
-* in your js
1. call the js sdk
window.fbAsyncInit = function() {
FB.init({
appId : {YOUR_APP_ID} , // App ID
version: 'v2.0',
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
oauth : true, // enable OAuth 2.0
xfbml : true // parse XFBML
});
};
// Load the SDK Asynchronously
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/sdk.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
}
3. Login into FB asking with these scopes
function Login()
{
FB.login(function(response) {
if (response.authResponse)
{
console.log(response.authResponse); // Get User Information.
} else
{
console.log('Authorization failed.');
}
},{scope: 'user_friends, publish_actions, status_update, read_stream, manage_friendlists'});// ' user_interests, user_likes, etc.. '
}
4. Get the logged user taggable_friends with a function such as:
var var friendsIDarray = [];
var user_friend_list;
function meTaggableFriends(){
FB.api(
"/me/taggable_friends",
function (response) {
if (response && !response.error) {
/* handle the result */
console.log(response)
for(var i=0; i<response.data.length; i++){
var data = response.data;
friendsIDarray.push(data[i].id);
}
user_friend_list = friendsIDarray.join();
}
}
);
5. Now, we have stored the token ids in user_friend_list for those friends we want to tag in our post
and we can use an Open Graph action like this in order to tag friends:
FB.api(
'me/{namespace}:{action}',
'post',
{
{object-type}:'http://example.com/object/', // make sure to have the apropiate og:type meta set
place:'https://example.com/place/', // open graph page with metas for location, id for a location page etc
tags: user_friend_list, // the tokens ids for those friens you wanna tag and you got on previous step
title: 'whatever',
message: 'like this, you tag friends #['+ONE_TOKEN_ID_FROM_TAGGABLE_FRIENDS+'] , #['+ONE_TOKEN_ID_FROM_TAGGABLE_FRIENDS+'] etc'
},
function(response) {
console.log(response)
}
);
you can find more information about it on:
https://developers.facebook.com/docs/opengraph/using-actions/v2.1
Hope you find it useful.
the error message "You, or this app's Open Graph Test User, must have published this action at least once" means: before you require this permission, you must call the api at least once.
I have occur this kind error before. when I require publish_actions permission, the facebook tell me this:
then I used my app call /me/feed api post a feed, then the error disappeared.
if you are the owner, developers or test users of the app, you can use these api before review approval. you can add roles for app in dashboard.

Categories

Resources