unity firebase database retrieving data - java

how to get the proper way or ShortCut or fastest way retrieving data of particular child from the firebase
baseRef.Child ("wordRun").Child("Players").Child(userid).Child("GameRun").Child("usercount").GetValueAsync ();
I try like something:-
example 1
var getTask =baseRef.Child ("wordRun").Child("Players").Child(userid).Child("GameRun").Child("usercount").GetValueAsync ();
yield return new WaitUntil(() => getTask.IsCompleted || getTask.IsFaulted);
if (getTask.IsCompleted) {
Debug.Log(getTask.Result.Value.ToString());
}
example 2:-
baseRef.Child("wordRun").Child("Players").Child(userid).Child("GameRun").Child("usercount").GetValueAsync .ContinueWith(task => {
if (task.IsFaulted) {
// Handle the error...
}
else if (task.IsCompleted) {
DataSnapshot snapshot = task.Result;
foreach ( DataSnapshot user in snapshot.Children){
IDictionary dictUser = (IDictionary)user.Value;
Debug.Log ("" + dictUser["usercount"]);
}
}
});
I want to get values write a single line in firebase database if anyone knew how got value in a single line in firebase then please give answer thank you for reading...
And Please Give me a way to get all data back in a class by getting GetRawJsonValue

you need to getting by the loop
foreach (var childSnapshot in args.Children) {
Debug.Log("ChildSnapshot"+childSnapshot..GetRawJsonValue());
}
and if you have any Class which have same data format then you try this
ClassName ClassObjectName = JsonUtility.FromJson<ClassName>(args.Snapshot.GetRawJsonValue());

Related

Loading all contacts using the Microsoft Graph API sometimes looses/skips pages

We have an application that loads all contacts stored in an account using the Microsoft Graph API. The initial call we issue is https://graph.microsoft.com/v1.0/users/{userPrincipalName}/contacts$count=true&$orderBy=displayName%20ASC&$top=100, but we use the Java JDK to do that. Then we iterate over all pages and store all loaded contacts in a Set (local cache).
We do this every 5 minutes using an account with over 3000 contacts and sometimes, the count of contacts we received due to using $count does not match the number of contacts we loaded and stored in the local cache.
Verifying the numbers manually we can say, that the count was always correct, but there are contacts missing.
We use the following code to achieve this.
public List<Contact> loadContacts() {
Set<Contact> contacts = new TreeSet<>((contact1, contact2) -> StringUtils.compare(contact1.id, contact2.id));
List<QueryOption> requestOptions = List.of(
new QueryOption("$count", true),
new QueryOption("$orderBy", "displayName ASC"),
new QueryOption("$top", 100)
);
ContactCollectionRequestBuilder pageRequestBuilder = null;
ContactCollectionRequest pageRequest;
boolean hasNextPage = true;
while (hasNextPage) {
// initialize page request
if (pageRequestBuilder == null) {
pageRequestBuilder = graphClient.users(userId).contacts();
pageRequest = pageRequestBuilder.buildRequest(requestOptions);
} else {
pageRequest = pageRequestBuilder.buildRequest();
}
// load
ContactCollectionPage contactsPage = pageRequest.get();
if (contactsPage == null) {
throw new IllegalStateException("request returned a null page");
} else {
contacts.addAll(contactsPage.getCurrentPage());
}
// handle next page
hasNextPage = contactsPage.getNextPage() != null;
if (hasNextPage) {
pageRequestBuilder = contactsPage.getNextPage();
} else if (contactsPage.getCount() != null && !Objects.equals(contactsPage.getCount(), (long) contacts.size())) {
throw new IllegalStateException(String.format("loaded %d contacts but response indicated %d contacts", contacts.size(), contactsPage.getCount()));
} else {
// done
}
}
log.info("{} contacts loaded using graph API", contacts.size());
return new ArrayList<>(contacts);
}
Initially, we did not put the loaded contacts in a Set by ID but just in a List. With the List we very often got more contacts than $count. My idea was, that there is some caching going on and some pages get fetched multiple times. Using the Set we can make sure, that we only have unique contacts in our local cache.
But using the Set, we sometimes have less contacts than $count, meaning some pages got skipped and we end up in the condition that throws the IllegalStateException.
Currently, we use microsoft-graph 5.8.0 and azure-identiy 1.4.2.
Have you experienced similar issues and can help us solve this problem?
Or do you have any idea what could be causing these inconsistent results?
Your help is very much appreciated!

Can't edit other Parse User objects , save In Background doesn't write in Parse Dashboard

I have been bonking my head everywhere on this problem , I would really need some help please !! I am pretty new to Android.
My problem is the following , I have completed the User Class with some columns , for example "Former Friends" which are a list of Strings .
I do a first query , then I find the Parseuser objects matching the query (which are not the logged in user) and then I try to fill those columns.
I also update the info for the logged in user
It properly works for the logged in user ,however I can't see the filled info for the other Parse object user
I tried modifying the write access for the first user (objects.get(0)) ,but it doesn't work
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.whereNotEqualTo("username", getCurrentUser().getUsername());
query.whereNotContainedIn("username",getCurrentUser().getList("Former_friends"));
query.findInBackground(new FindCallback<ParseUser>() {
#Override
public void done(List<ParseUser> objects, ParseException e) {
if (e == null) {
if (objects.size() > 0) {
// Here I just add the first object to a list and I update the current user data ,that works fine
List<String> aList = ParseUser.getCurrentUser().getList("Former_friends");
aList.add(objects.get(0).getString("username"));
ParseUser.getCurrentUser().put("Former_friends", aList);
ParseUser.getCurrentUser().saveInBackground();
ParseUser userfound =objects.get(0);
// The two following Lines doesn't work. I don't see "Any String" in the ParseDashboard "Name" columns..
userfound.put("Name","Any String");
userfound.saveInBackground();
There are no bugs , but no update for the non-logged-in user
Big thx,
Serge
For security reasons, in Parse Server, one user cannot change another user object directly from client side. If it were possible, a bad user could erase all other users data, for example.
So this operation requires you to write a cloud code function. You should have a cloud function similar to this one here:
Parse.cloud.define('formerFriends', async request => {
const query = new Parse.Query(Parse.User);
query.notEqualTo('username', request.user.getUsername());
query.notContainedIn('username', request.user.get('Former_friends'));
const objects = await query.find({ useMasterKey: true });
if (object.length > 0) {
const aList = request.user.get('Former_friends');
aList.add(objects[0].getUsername());
request.user.set('Former_friends', aList);
await request.user.save();
const userfound = objects[0];
userfound.set('Name', 'Any String');
await userfound.save(null, { useMasterKey: true });
}
});
And then call the cloud function from Android like this:
HashMap<String, Object> params = new HashMap<String, Object>();
ParseCloud.callFunctionInBackground("formerFriends", params, new FunctionCallback<Float>() {
void done(Object result, ParseException e) {
if (e == null) {
// success
}
}
});

Parse Server How to get an object ID by query?

If we wanna get an object ID we should do this:
String objectId = gameScore.getObjectId();
but what if we wanna get an object ID by a query? Like this:
ParseQuery<ParseObject> query = ParseQuery.getQuery("mytable");
query.whereEqualTo("Title", "Adrians Book");
List<ParseObject> results = null;
try {
results = query.find();
if(!results.isEmpty()) {
String objectId = results.getObjectId();
}
} catch (com.parse4cn1.ParseException e) {
Dialog.show("Err", "Something went wrong.", "OK", null);
}
Sounds interesting don't you think? I wish it could be possible. As you can see in this example the query will get a value from a specific object in the table which could track for the object ID then returning it as well. ParseQuery class should be implemented with getObjectId(). Because by this way applications always could have access to object IDs from the query even after applications get restarted so in the first example the gameScore which is actually an instance of ParseObject would lost reference to the Database after restarting. Getting object IDs by the query it would be able to program applications to get object IDs automatically without the need of doing it manually nor depending on instances of ParseObject.
#Shai Almog: Thank you very much for taking your time to look at the ParseQuery documentation.
I accidentally figured out how to get this done!
ParseQuery<ParseObject> query = ParseQuery.getQuery("mytable");
query.whereEqualTo("Title", "Adrians Book");
List<ParseObject> results = null;
try {
results = query.find();
if(!results.isEmpty()) {
String objectId = results.get(0).getObjectId();
System.out.println(objectId);
}
} catch (com.parse4cn1.ParseException e) {
Dialog.show("Err", "Something went wrong.", "OK", null);
}
Yep, after adding the method .get(index) it allows you to access the method .getObjectId() since results is a list of a ParseObject, then the respective objectId of your query result will be printed in the console! I'm pretty glad it's working because I won't need to serialize each object for now which would be a pain.
Also if you wanna set an instance of ParseObject with an existing objectId in case you need to update something in your Database, you can use this example:
ParseObject po = ParseObject.create("mytable");
po.setObjectId(//YOUR DESIRED OBJECTID HERE, AS LONG AS IT EXISTS IN THE DATABASE);
As far as I know you need to get the whole object then query it's ID. I don't see a query id method here https://github.com/sidiabale/parse4cn1/blob/41fe491699e604fc6de46267479f47bc422d8978/src/com/parse4cn1/ParseQuery.java

Retrieve Array from Parse

In my endWorkout.java file, I am saving data into my Parse database using the following logic:
// Parse Storage
ParseObject testObject = new ParseObject("TestOne");
testObject.put("Device", ParseInstallation.getCurrentInstallation());
testObject.put("Reps", inputList);
testObject.saveInBackground();
Where I am first storing my Device ID for authentication purposes, and then storing inputList which is an ArrayList of integers.
In my Parse database, the data is properly saved, as shown below:
Now in my MainActivity.java, I would like to retrieve all the data in the Reps field of the Parse database for a single device. For example, the device yhmrKgokfS has 6 Arrays in the Parse database, I would like to sequentially retrieve each of them to display in a ListView on the screen.
Here is the logic I am trying to use:
List<ParseObject> importList = new ArrayList<ParseObject>();
//parse import list
ParseQuery<ParseObject> query = ParseQuery.getQuery("TestOne");
query.whereEqualTo("Device", ParseInstallation.getCurrentInstallation());
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> repList, ParseException e) {
if (e == null) {
Log.d("Reps", "Retrieved " + repList.size() + " reps");
} else {
Log.d("Reps", "Error: " + e.getMessage());
}
}
});
importList = repList;
I first want to make sure I'm importing from the current device, so I need to check if the Device field matches ParseInstallation.getCurrentInstallation(). Then I want to go ahead and get the first Reps array. However the last line importList = repList; does not work.
How can I go about achieving what I'm trying to do?
query.findInBackground works in asynchronous way. In other words, the line that you set the importList is executed after the line query.findInBackground. However, the query.findInBackground will make a network call that takes time. So if you want to use the repList when it is ready, you have to use it in done method where you are use the network call is done. Hope this helps.
Regards.
As #kinkspeech mentioned you need to move your line importList = repList; to your callback. And I suggest that you change it as follows:
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> repList, ParseException e) {
if (e == null) {
Log.d("Reps", "Retrieved " + repList.size() + " reps");
importList.addAll(replist);
} else {
Log.d("Reps", "Error: " + e.getMessage());
}
}
});

How to use Gson to deserialize to a class containing an ArrayList?

I'm using the Azure SDK, which uses Gson to serialize and deserialize objects to upload to their Mobile Services API. I've had success doing this with a customs class of primitives only, as in the examples given in the Gson User Guide. I'd like to do this with a custom class that contains an ArrayList. I'd even settle for a List or an Array, I'm not too picky. Here's my class:
public class clsUser {
private int UserID;
private String UserName;
private String UserStatus;
public ArrayList<String> UserEmails;
Gson appears to serialize the class when sending to the server this way:
{ UserEmails: [ 'myEmail#gmail.com', 'myEmail2#yahoo.com' ],
UserStatus: 'A',
UserName: 'Scott',
UserID: 1 }
On the server, I'm storing it all in a relational SQLServer database, so I'm keeping UserEmails as a String in there, and trying to bring it back out as an array.
However back on my Android/Gson/Client side, I'm getting an error:
java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING
I suspect that the problem is that SQLServer is returning UserEmails with surrounding quotes. I'm not sure how to fix this. Complicating matters is that the Gson implementation is inside the Azure SDK, so I don't think I could even write a custom deserializer if I wanted to. Any suggestions on fixing this? Thanks in advance!
Konrad's comment helped me past this stumbling block. If the problem is that the server is returning this field as a String, then all I needed to do was insert a step to convert it to an Array before returning the data to my client. (Yay for dynamic types in Javascript!) My updated server script is below:
function lookup(request, response) {
var UserID = request.query.UserID;
if (UserID == null || isNaN(parseFloat(UserID))) {
response.send(400, "Invalid Parameters (" + UserID + ")");
} else {
request.service.mssql.query("select ID UserID, Full_Name UserName, Email_Addresses UserEmails, Status UserStatus from User_List where ID=?;", [UserID], {
success: function (results) {
if (results.length > 0) {
//*** Added this line below to convert String back to Array ***//
results[0].UserEmails = results[0].UserEmails.split(',')
response.send(200, results[0]);
} else {
response.send(200, []);
}
}, error: function (err) {
response.send(500, {"Message" : "Lookup error = " + err});
}
});
}
}

Categories