Retrieve data from ParseUser after using FindAsync - list

I've created a number of users in Parse. There're Facebook users and non-Facebook user. For each Facebook user I've saved an extra column of "facebookID".
Now I'd like to get all the ParseUsers that are Facebook Users. So I applied a Task to query the users with "facebookID" in them.
var Task = ParseUser.Query.WhereExists("facebookID").FindAsync().ContinueWith(t=>{
if (t.IsFaulted || t.IsCanceled) {
Debug.Log ("t.Exception=" + t.Exception);
//cannot load friendlist
return;
}
else{
fbFriends = t.Result;
foreach(var result in fbFriends){
string id = (string)result["facebookID"];
//facebookUserIDList is a List<string>
facebookUserIDList.Add(id);
}
return;
}
});
The above code works perfectly. However, I'd like to get more data from each Facebook User, for example, the current_coins that the user has. So I change the foreach loop to:
foreach(var result in fbFriends){
string id = (string)result["facebookID"];
int coins = (int)result["current_coins"];
//facebookUserIDList is a List<string>
facebookUserIDList.Add(id);
}
I've changed the facebookUserIDList into a List<Dictionary<string,object>> instead of a List<string> in order to save the other data as well. But the foreach loop does not run at all. Does it mean I can only get the facebookID from it because I specified WhereExists("facebookID") in FindAsync()? Can anybody explain it to me please?
Thank you very much in advance.

it should contain all Parse primitive data type(such as Boolean, Number, String, Date...) for each Object. but not Pointers nor Relation.
for Pointers, you can explicitly include them in the result using the "Include" method
for any ParseRelation you have to requery them

Related

APEX: Assigning a Map without a Key to a List

Sorry for the newbie question. Learning Apex here. Been working on an issue for several hours and can't seem to needle it out.
I have a JSON that I need converted to a List... the JSON is retrieved via an API. The code is pretty simple, it is only a couple of lines.
The JSON looks like this:
{"id":1,"abbreviation":"ATL","city":"Atlanta","conference":"East","division":"Southeast","full_name":"Atlanta Hawks","name":"Hawks"}
And the code I am told to use to retrieve it looks like this:
Map<String, Object> resultsMap = (Map<String, Object>) JSON.deserializeUntyped(results.getBody());
Based on the JSON provided, there does not appear to be a MAP key being assigned, so I have no idea how to get it so that I may assign it to a List...
I've already tried assigning it directly to a List, but I didn't get much success there either.
I've tried this already:
List<Object> other = (List<Object>) results.get('');
I've also tried this:
List<Object> other = (List<Object>) results.keySet()[0];
I'm sure it is something simple. Any help would be appreciated.
Thanks
You cant convert the map to a list without an id. Alternatively why to convert it to List. Use the map itself. Below is a code example of how you can use it using your JSON response. For example, I want to insert this JSON response into the contact record, so I can map it using the MAP itself.:
#RestResource(urlMapping='/URIId/*')
global class OwneriCRM {
#HttpPut
global static String UpdateOwnerinfo(){
RestRequest req= RestContext.request;
RestResponse res= RestContext.response;
res.addHeader('Content-type','application/JSON');
Map<String,Object> responseresult=new Map<String,Object>();
Map<String,Object> results= (Map<String,Object>)JSON.deserializeUntyped(req.requestBody.toString());
List<contact> insertList = new List<contact>();
for (String key : results.keySet()){
System.debug(results.get(key));
contact c= new contact();
c.ContactField__C = results.get(id);
c.ContactField1__C = results.get(city);
c.ContactField2__C = results.get(conference);
c.ContactField3__C = results.get(division);
c.ContactField3__C = results.get(full_name);
c.ContactField3__C = results.get(name);
insertList.add(c);
}
if(!insertList.Isempty()){
update insertList;
}
Question can be disregarded. Not sure if there is a way to withdraw the question.
Question was based on the fact that previous APIs had been sent in the following format:
{"data": {"more stuff": "stuff"} }
And the map key was 'data' with a list. In this scenario, the whole API was a list and the keys to the map were set in place with the actual values instead.

Best attribute to use from AWS CognitoUser class for primary key in DynamoDB

I am trying to make the primary key of my dynamodb table something like user_uuid. The user is being created in AWS Cognito and I can't seem to find a uuid like field as part of the CognitoUser class. I am trying to avoid using the username as the pk.
Can someone guide me to the right solution? I can't seem to find anything on the internet regarding a user_uuid field and for some reason I can't even find the documentation of CognitoUser class that is imported from "amazon-cognito-identity-js";
Depends if you plan to use email or phone as a 'username'. In that case, I would use the sub because it never changes. But, the sub is not k-sortable so that requires the use of an extra DB item and index/join to make users sortable by date added. If you plan to generate your GUID/KSUID, and only use email/phone as an alias, then I would use the 'username' as a common id between your DB and userpool.
Good luck with your project!
FWIW - the KSUID generators found in wild are massively overbuilt. 3000+ lines of code and 80+ dependencies. I made my own k-sortable and prefixed pseudo-random ID gen for Cognito users. Here's the code.
export function idGen(prefix: any) {
const validPrefix = [
'prefix1',
'prefix2'
];
//check if prefix argument is supplied
if (!prefix) {
return 'error! must supply prefix';
}
//check if value is a valid type
else if (validPrefix.indexOf(prefix) == -1) {
return 'error! prefix value supplied must be: ' + validPrefix;
} else {
// generate epoch time in seconds
const epoch = Math.round(Date.now() / 1000);
// convert epoch time to 6 character base36 string
const time = epoch.toString(36);
// generate 20 character base36 pseudo random string
const random =
Math.random().toString(36).substring(2, 12) +
Math.random().toString(36).substring(2, 12);
// combine prefix, strings, insert : divider and return id
return prefix + ':' + time + random;
}
}
Cognito user unique identifiers can be saved to a database using a combination of the "sub" value and the username, please refer to this question for a more lengthy discussion.
In the description of amazon-cognito-identity-js (found here, use case 5), they show how to get the userAttributes of a CognitoUser. One of the attributes is the sub value, which you can get at for example like this:
user.getUserAttributes(function(err, attributes) {
if (err) {
// Handle error
} else {
// Do something with attributes
const sub = attributes.find(obj => obj.Name === 'sub').Value;
}
});
I couldn't find any documentation on the available user attributes either, I recommend using the debugger to look at the user attributes returned from the function.

Trouble accessing child objects in Firebase

I'm trying to pull a list of connected users in Firebase to simply populate a select dropdown. My problem is that I can't seem to access the child objects properly.
Using connectedUsers.userName (see below code) works but only for my own user data, it doesn't pull anything else.
It seemed to me like changing "myUserRef.on" to "userListRef.on" and using something like "snapshot.child('userName').val()" should work but it just throws undefined. The same goes for "connectedUsers.child.userName", I'm sure I'm missing something simple here.
In the below code by changing to "userListRef.on('child_added', function(snapshot)" I can successfully add and remove user data from Firebase, and log all of the objects to the console and all data looks fine when I drill down the objects. I just need a way to access that data so I can put all connected users into a select dropdown or remove them from it when they disconnect.
var userListRef = new Firebase('https://myaccount.firebaseIO.com/users/');
var myUserRef = userListRef.push();
// ADD USER DATA TO FIREBASE
var userId = $('#myIdInput').val();
var userName = $('#nameInput').val();
myUserRef.push({userId: userId, userName: userName});
// READ USER OBJECTS AND FIRE ADDUSER FUNCTION
myUserRef.on('child_added', function(snapshot) {
var connectedUsers = snapshot.val();
console.log(addUser);
//addUser(connectedUsers.userId, connectedUsers.userName);
});
// ADD USER TO SELECT DROPDOWN
function addUser(userId, userName) {
var modSelect = $('#tsmmodsendto');
modSelect.append($('<option></option>').attr("value", userId).text(userName));
}
// READ USER OBJECTS AND FIRE REMOVEUSER FUNCTION
myUserRef.on('child_removed', function(snapshot) {
var connectedUsers = snapshot.val();
console.log(removeUser);
//removeUser(connectedUsers.userId, connectedUsers.userName);
});
// REMOVE USER TO SELECT DROPDOWN
function removeUser(userId, userName) {
var modSelect = $('#tsmmodsendto');
modSelect.append($('<option></option>').removeAttr("value", userId).text(userName));
}
// ON DISCONNECT REMOVE USER DATA FROM FIREBASE
myUserRef.onDisconnect().remove();
The code you've written won't work properly because each user is writing to:
/users/PUSH_ID/PUSH_ID
And is then listening at:
/users/PUSH_ID
So every client is going to be listening only to its own data and will never see anyone else's data. In order to view other people's data, you need to all be listening / writing to the same path.
In your question you mention you see "undefined" if you change to listening at /users. Could you simplify your code, and use that approach, and perhaps then I can provide a more helpful answer?
Or if I'm not understanding correctly, please simplify and clarify your question.

Accessing Item Fields via Sitecore Web Service

I am creating items on the fly via Sitecore Web Service. So far I can create the items from this function:
AddFromTemplate
And I also tried this link: http://blog.hansmelis.be/2012/05/29/sitecore-web-service-pitfalls/
But I am finding it hard to access the fields. So far here is my code:
public void CreateItemInSitecore(string getDayGuid, Oracle.DataAccess.Client.OracleDataReader reader)
{
if (getDayGuid != null)
{
var sitecoreService = new EverBankCMS.VisualSitecoreService();
var addItem = sitecoreService.AddFromTemplate(getDayGuid, templateIdRTT, "Testing", database, myCred);
var getChildren = sitecoreService.GetChildren(getDayGuid, database, myCred);
for (int i = 0; i < getChildren.ChildNodes.Count; i++)
{
if (getChildren.ChildNodes[i].InnerText.ToString() == "Testing")
{
var getItem = sitecoreService.GetItemFields(getChildren.ChildNodes[i].Attributes[0].Value, "en", "1", true, database, myCred);
string p = getChildren.ChildNodes[i].Attributes[0].Value;
}
}
}
}
So as you can see I am creating an Item and I want to access the Fields for that item.
I thought that GetItemFields will give me some value, but finding it hard to get it. Any clue?
My advice would be to not use the VSS (Visual Sitecore Service), but write your own service specifically for the thing you want it to do.
This way is usually more efficient because you can do exactly the thing you want, directly inside the service, instead of making a lot of calls to the VSS and handle your logic on the clientside.
For me, this has always been a better solution than using the VSS.
I am assuming you are looking to find out what the fields looks like and what the field IDs are.
You can call GetXml with the ID, it returns the item and all the versions and fields set in it, it won't show fields you haven't set.

How can I get a SharePoint user profile via the "Friendly Name" using the SP web service?

I'm retrieving a list of names from a SharePoint list in my client program. The names are populated from a name picker in SharePoint. In the XML returned from the list query, the list looks like this:
"#10;#Some Name;#12;#Another Name;#15;#Yet AnotherName"
My program needs to get the account name (or the email address) of each user. I can use GetUserProfileByName("domain\\username"), but I don't have the account name. I can't do something like GetUserProfileByName("Some Name") because it has to be the account name.
The number before each name is the index or the ID, but I can't use GetUserProfileByIndex(10) because I have to be managing my own data or have administrator credentials.
So basically it is providing me with two important pieces of information, but I can't retrieve any further information using them.
Are you sure the number is an index, i think it might be the userid for the site collection. And it seems to be an odd sort of user list too, but anyway:
string result = "#10;#Some Name;#12;#Another Name;#15;#Yet AnotherName";
string[] users = result.Substring(1).Split(new string[2] { ";", "#" }, StringSplitOptions.RemoveEmptyEntries);
for (int j = 0; j < users.Length; j = j + 2) {
using (ClientContext context = new ClientContext("http://yoursite")) {
List list = context.Web.SiteUserInfoList;
ListItem item = list.GetItemById(int.Parse(users[j]));
context.Load(item, i => i.Id, i => i["Name"]);
context.ExecuteQuery();
object username = item["Name"];
}
}
I have a very messy solution working, but I'd love to hear of some ideas for a proper/elegant solution.
Right now I'm using GetListItems on the UserInfo list and creating a dictionary of ows_ImnName and ows_Name entries, then parsing the string from the list query into the names and using them as lookup values.
There has to be a better way.