I've been trying to get a registration/login form going on in my android application, and I've been trying to do so with the help of the Parse Core by storing users' information as an Object.
I've gotten everything to work perfectly. Well...almost.
The only thing that I need to do now is to add a unique user ID for every user registered and increment it by 1 everytime a new user registers.
I've tried using the Users.increment("userID", 1);, and it works, but it doesn't go over the value 1.
This is what I'm trying to do:
This is my registration form code:
ParseObject Users = new ParseObject("Users");
Users.increment("userID", 1);
Users.put("first_name", firstname);
Users.put("last_name", lastname);
Users.put("email", email);
Users.put("password", password);
Users.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e == null) {
//User registered successfully.
Toast.makeText(RegisterActivity.this, "Registration successful."
, Toast.LENGTH_SHORT).show();
//Take user to LoginActivity.
startActivity(new Intent(RegisterActivity.this, LoginActivity.class));
} else {
//User registration failed.
Toast.makeText(RegisterActivity.this, "Registration failed."
, Toast.LENGTH_SHORT).show();
//Show error.
e.printStackTrace();
}
}
});
Thank you for your time.
When you write ParseObject user = new ParseObject("Users"); you are defining a new row of the table, so if you call increment() you will be incrementing just that row's value.
If you want to do something different I can help you out. The answer is different based on what you want to do:
keep a total count of users;
add a unique identifier to each user;
...
and why you want to do it. Note that each user has already a unique identifier, in the objectId field, and that can be helpful in most, if not all, applications.
Ok, now I have seen your second screenshots and understand what you are trying to achieve. That is surely possible, but I would discourage it. For example, let's say you manage to write working code. What happens if..:
The user with userID = 1 deletes his account? Are you going to scale down the userIDs of all the users that registered after (userID = 2, 3, ...)? That is hard and mostly useless.
Two or more users register at the same time? That would determine serious synchronization issues and you could end up having two (or more) users with the same userID.
So my answer is: what you want is possible only with hard work, and probably useless. If you give additional info about why you want to do that, we can find a better way.
Related
Well, not exactly at the same time. More like one after the other, in a for-loop.
Problem: So in some instances, the code I used did manage to create multiple accounts but it often gives me the error that the user is null and fails to write to the database.
The code:
Database db = FirebaseDatabase.getInstance().getReference();
String password = "1234567"; // Same password for all accounts
ArrayList emailArray = new ArrayList(); // For example, 20 premade emails
for (int i = 0; i < emailArray.size(); i++){
mAuth.createUserWithEmailAndPassword((String) emailArray.get(i), password).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (mAuth.getCurrentUser() != null) {
String userId = mAuth.getCurrentUser().getUid(); // This value is returning null
// Writing a bunch of things to the database for each user
db.child(userId).child("name").setValue(...)
...
mAuth.signOut();
}
}
});
}
I think I may have to use an AuthStateListener but I am unsure and I don't know how to implement it. How would I go about accomplishing this? Please let me know if I should include anything else in my post. Thank you!
You should not use the client-side Android SDK to create multiple users like this. There's a significant chance that your app will be flagged for abuse, and locked out of the system.
For administrative use-cases, use the Admin SDK in a trusted environment.
On a code level, the problem occurs because there's only one value for mAuth.getCurrentUser() and you're trying to create all the users in parallel. You'll need to wait for each createUserWithEmailAndPassword to be completed, before starting on the next one. But as said above: this approach is flawed to begin with, so I don't recommend pursuing this path further.
I'm trying to write messenger app using Firebase.
In database I have a few entries, which are User.class objects. I'm trying to write function which can download User object from database. I though that it'd be better to build separate class (UserManager) for this task, because I don't like making mess in code. But there is a problem, because in onCreate method I need to use User object to download some additional info from database to create conversation list, so downloading user from server should be done before that. Also if user is not in database, it should create and push User to database using FirebaseAuth (I've got that working).
Should I build class extending AsynchTask, and there put downloading user, and then updating UI with the data downloaded after user ?
How do I know if the user was already downloaded. Probably I should build some listener but I don't know how to do that.
Additional question:
If I use this reference with value listener, do i get a user object or some value from inside of the object?
DatabaseReference userReference = FirebaseDatabase.getInstance().getReference().child("users/" + mUserID);
Here is my database:
Each entry key is userID from FirebaseAuth for easier implementation.
I've been cracking my head on this for a few days and tried different approaches. I'll apriciate any help. I think, that some code or a scheme would be a huge help.
How do I know if the user was already downloaded?
You can add a flag to each user with the value of false and once you have downloaded the user object, to set the value to true but this is not how things are working with Firebase. You cannot know when a user from the database is completed downloaded becase Firebase is a realtime database and getting data might never complete. That's why is named a realtime database because in any momemnt the data under that User object can be changed, properties can be added or deleted.
You can use a CompletionListener only when you write or update data and you'll be notified when the operation has been acknowledged by the Database servers but you cannot use this interface when reading data.
If I use this reference with value listener, do i get a user object or some value from inside of the object?
If the value that you are listening to is a User object, then you'll get a User object. If the value is another type of object, which can also be a String (which is also an object) then you'll get that type of object, which can also be a String object. Remember, that only the keys in a Firebase database are always strings.
Maybe this part of my code will help you figure out:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("users")
.child(mUserID);
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e(TAG, "DatabaseError: " + databaseError.getMessage());
}
});
I'm trying to implement a basic web application from the values that we are getting from web-service, it will include two datatables, each of them need to be populated in server-side.
For example, web-service have a structure like this ( Let's say these are books)
Firstly i am getting the string GUID value for the objects that i want to get an information, after that i am sending a request with the parameter of this GUIDs to service to get information XML for these book objects that includes name, page and author of them.
But as an important information, my servlet needs to get these values dynamically as soon as the page of datatable is changed, if this datatable will include 30 book ( i will get the 30 guid firstly so i can clarify that ) after that, send one request for 10 of them to show them on first page of datatable, if user clicked on page two, server behind needs to send request for the other group of ten and returns me result to show on the table.
I tried to implement the structure below :
http://www.codeproject.com/Articles/359750/jQuery-DataTables-in-Java-Web-Applications#ServerSideProcessing
but it populates a table with the DataRepository ones with all of them, so with this point of view i can't use it dynamically as i totally requested.
The main need for this, XML return for many objects needs so long time.
So do you know any example link or tutorial such a need for this ?
Thank you for informations in advance!
#Hayra, thanks for providing the Code Project link to the JQuery-DataTable example, it is very helpful. This is something that I might implement soon.
What I understood from the example, the JQuery-DataTable keeps track for you specific parameters that will allow you to return the exact number of records. The specific parameters that you need are "iDisplayStart" and the iDisplayLength". The "iDisplayLength" is set when the user specifies 10 records per page and the iDisplayStart, will is set when the page number changes.
So look at the code in the Code Project example doGet Method, this section of the code returns only the subset of records back to your table.
JQueryDataTableParamModel param = DataTablesParamUtility.getParam(request);
if(companies.size()< param.iDisplayStart + param.iDisplayLength) {
companies = companies.subList(param.iDisplayStart, companies.size());
} else {
companies = companies.subList(param.iDisplayStart, param.iDisplayStart + param.iDisplayLength);
}
try {
JsonObject jsonResponse = new JsonObject();
jsonResponse.addProperty("sEcho", sEcho);
jsonResponse.addProperty("iTotalRecords", iTotalRecords);
jsonResponse.addProperty("iTotalDisplayRecords", iTotalDisplayRecords);
for(Company c : companies){
JsonArray row = new JsonArray();
row.add(new JsonPrimitive(c.getName()));
row.add(new JsonPrimitive(c.getAddress()));
row.add(new JsonPrimitive(c.getTown()));
data.add(row);
}
jsonResponse.add("aaData", data);
response.setContentType("application/Json");
response.getWriter().print(jsonResponse.toString());
} catch (JsonIOException e) {
e.printStackTrace();
response.setContentType("text/html");
response.getWriter().print(e.getMessage());
}
I hope this help
Ok, I am building an app in client and it needs to take data from DB. The app won't take all data from DB all at once but based on the pagination.
It has a simple textbox for user to enter text and a Button to search data.
Requirements:
-If the system already downloaded the data from a certain pageNo, then it won't call to server again.
-Each time it successfully called to server it needs to remember the pageNo, so that next time when user searching for that exact term it
will search for pageNo=pageNo+1 cos we searched for pageNo
already.
So here is what i did:
private HashMap<String, Integer> wordPageNoHashMap=new HashMap<String, Integer>();
button.addClickHandler(new ClickHandler(){
#Override
public void onClick(ClickEvent event) {
int pageNo=0;
if(wordPageNoHashMap.containsKey(word)){
pageNo=wordPageNoHashMap.get(word); //note: page no only increase if found result
}
else{
pageNo=1;
wordPageNoHashMap.put(word, pageNo);
}
callToDB(word,pageNo);
}
});
public void resultFromDB(ServerResult result){
int pageNo=result.getPageNo();
String word=result.getWord();
List<String> textResult=result.getResult();
if(textResult!=null && textResult.size()>0){
pageNo++;
wordPageNoHashMap.put(word, pageNo);
//show data here
}
else{
//show err here
}
}
I putting pageNo++ at the result not at the time we call.
Am i designning it ok?
or
Can u do a better design?
Assuming my understanding is correct, for a search query I will retrieve a reasonable number of records from the DB (say 500) and store it in something like a PagedListHolder and set the per page data to whatever number you want(say 20).
Now I have two options, when the user clicks next I will simply call the nextPage() and retrieve the data set. (This might be applicable for infinite loading)
Or if the user is clicks on a particular page number (conventional pagination), I will pass on the page number to the setPage() method and retrieve the elements from that page.
I have used the PagedlistHolder example to make it easy for you to understand. You may use any similiar Class if available, or you can write one.
I think this achieves your objective of not hitting the DB for the same set of data.
Let me know if it helped.
I have a problem which is related to logic than a technology, here is a scenario, (I am using Spring + Hibernate)
I need to read some data from database to return back to page on every get request, but I thought some hack here that what if using some script someone reload page very frequently, this will cause that many calls to server, for this I thought to read data and put them in global variables or class variable, by doing so i end up writing very weird code many global variable and stupid way to give them initial value like for a variable user-status which is a byte type variable I have given -2 as initial value so that my inner logic can understand no value is set for this variable from database, below is my code
#Controller
/* #Secured("hasRole('ROLE_USERS')") */
#RequestMapping("member")
public class ApplyRoles {
#Autowired
private UserInformationForAccessApplication checkUserStatus;
// we will initialize variables to avoid auto-initialize by constructor
private byte userStatus = Constant.IntializationOfGlobalVariable.GLOBALINIT,
requesttype = Constant.IntializationOfGlobalVariable.GLOBALINIT,
access = Constant.IntializationOfGlobalVariable.GLOBALINIT;
Map<String, Object> accessnrole;
Map<String, String> country;
Map<String, String> roleArray;
#Autowired
StudentEnrollmentApplication enrollmentApplication;
#Autowired
SystemProperties systemProperties;
#Autowired
EmployeeEnrollmentApplicationResume employeeEnrollmentApplicationResume;
#Autowired
AccessEnrollmentProcessing accessEnrollmentProcessing;
private String role = Constant.IntializationOfGlobalVariable.ROLENOTSET,
fname, lname;
#RequestMapping(value = "/user", method = RequestMethod.GET)
public String checkingUserStatus(Model model, HttpSession session,
Authentication authentication) {
String sessionemail = "yashprit#gmail.com";// (String) session
// .getAttribute(Constant.SessionAttributes.LOGGEDINUSER);
// first check global value, if found set than don't fetch from database
if (userStatus == Constant.IntializationOfGlobalVariable.GLOBALINIT) {
// get user status from MySQL Database
userStatus = checkUserStatus.checkStatus(sessionemail).get(0);
if (!(userStatus == Constant.UserRoleApplicationStatus.NOTAPPLIED)) {
access = checkUserStatus.checkStatus(sessionemail).get(1);
model.addAttribute(Constant.SystemName.ACCESS, access);
}
}
if (!(userStatus >= Constant.UserRoleApplicationStatus.NOTAPPLIED || userStatus <= Constant.UserRoleApplicationStatus.REJECTED)) {
model.addAttribute("error", "User status is not avaible");
return "redirect:error/pagenotfound";
} else if (userStatus == Constant.UserRoleApplicationStatus.NOTAPPLIED) {
if (requesttype == Constant.IntializationOfGlobalVariable.GLOBALINIT) {
// get request type from MongoDB database
requesttype = checkUserStatus.getRequestType(sessionemail);
}
if (!(requesttype == Constant.RequestType.NORMALEBIT || requesttype == Constant.RequestType.INVITEBIT)) {
model.addAttribute("error",
"Facing Technichal Issue, Please try again");
return "redirect:error/pagenotfound";
}
if (requesttype == Constant.RequestType.INVITEBIT) {
if (!(Byte.parseByte((String) accessnrole
.get(Constant.SystemName.ACCESS)) == Constant.Access.USERBIT)) {
accessnrole = checkUserStatus
.getAccessAndRole(sessionemail);
}
if (accessnrole.get(Constant.SystemName.ACCESS).equals(
Constant.Database.ERRORMESSAGE)
|| accessnrole.get(Constant.SystemName.ROLE).equals(
Constant.Database.ERRORMESSAGE)) {
model.addAttribute("error",
"Facing Technichal Issue, Please try again");
return "redirect:error/pagenotfound";
}
model.addAttribute(Constant.SystemName.ACCESSNROLE, accessnrole);
model.addAttribute(Constant.SystemName.REQUESTTYPE, requesttype);
}
}
model.addAttribute(Constant.SystemName.USERSTATUS, userStatus);
return "member/user";
}
}
to avoid global variable i thought of suing cookies, because I don't want to call database on every page reload in same session, once its loaded for a session than I don't have to call to database.
Anything that can help to to redesign above part of code is much appreciated
thanks
There are really 2 things that you are considering, and correctly me if I'm wrong, but:
Caching on the server (in your Java application) to avoid doing a database lookup multiple times for the same data.
Avoid the client (browser) from sending multiple requests to the server.
The first can be resolved using caching which is available in spring uses annotations on any given method. The documentation is available here.
The second is a bit more tricky and I' leave it for now unless you discover a performance problem. It's again possible to do in Spring and takes advantage of the HTTP protocol and caching controls available in the HTTP header to inform the browser how long to cache responses.
What you are thinking about is called a "cache". It is a standard Computer Science way of doing things and they have been doing research on how to use caches for as long as there have been computers.
You might want to go do some reading on the subject. I found this one by Googling "cache tutorial java" http://javalandscape.blogspot.com/2009/01/cachingcaching-algorithms-and-caching.html
In simplest terms (a one item cache) what you want is to store some data object that you recently took some time to come up with. But you also have to have some sort of identifier so you can tell if the next request is asking for the same data. If it isn't, you have to do all the work over. If it is the same data, you just return it again.
So the algorithm works something like this in this simple case:
if (storedData != null && storedRequestInfo == userRequest.requestInfo) {
return storedData;
}
storedData = youCalculateTheRequestedData();
storedRequestInfo = userRequest.requestInfo;
return storedData;
Its not any real programming language, just something to show you how it works.
The requestInfo is whatever comes in with the request that you use to look up your database stuff. You save it in storedRequestInfo after any calculation.
This shows it as returning some data to the user, that's what is in storedData.
It's a simple, one-element cache.
(To expand on this, you can store the storedRequestInfo and storedData in the session and you end up with one of these stored for each user. You can also use a java Map and store a bunch of storedData. The problem is to decide how to limit your memory use. If you store too many of these for each user, you use up too much memory. So you limit how many each user can have either by size or by count. Then you have to decide which one to delete when it gets too big. In the simple case, you always delete, in essence, the stored one and store a new one.
I noticed your comment. ECache is just a big fancy Map in the terms I used above. I don't know if it's naturally session dependent but it can be made that way by adding the session id to the cache key.)