My app has a registration page wherein only those users who enter the right passcode are allowed to register. This passcode is stored inside firebase database inside a child called "Councilpasscodes". After entering the passcode the user should press the submit button, after comparing the two passcodes the user should be allowed to register if the passcodes are same.
This is the code for comparing the edit text string and the child value:
mpasscode=FirebaseDatabase.getInstance().getReference().child("Councilpasscodes");
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final String passcode1=editText.getText().toString().trim();
mpasscode.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String passc= (String) dataSnapshot.child("passcode").getValue();
if (passcode1.equals(passc)){
//do something
}else if(!passcode1.equals(passc)){
//do something
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
The problem is after pressing the submit button it is not really checking the two strings i.e. if (passcode1.equals(passc)) and if(!passcode1.equals(passc)) is not being called even after entering the right passcode. I am not sure what is wrong with the code as I am new to app development.Any help is appreciated.Thank you.
EDIT:
I think it is not executing addListenerForSingleValue at all. I am not sure why is this happening.
Alright mate. The reason why your ValueEventListener's onDataChange isn't getting called is that you're not authorized to edit or read your database. This happens because the default security settings for a firebase real-time database disallows any read or write without an authenticated user. To prove this observe your warning logs inside Android Monitor. (The blue ones.) It will show a caught exception mentioning permission denied from Firebase as soon as you click submit.
Read about Firebase security from here.
For a quick solution what you can do is, you can allow read or writes without any sort of authentication. To do that edit your Realtime database rules and add this instead of what's written there.
{
"rules": {
".read": true,
".write": true
}
}
I'm also gonna attach a screenshot for reference. You'll find this screen inside the firebase console. Inside the console click on your project and then on Database to the left as shown.
.
This is a security lapse none the less, so to set up proper Authentication from your app, follow these steps.
https://firebase.google.com/docs/auth/android/start/
Also, add a toString() to dataSnapshot.child("passcode").getValue() like this to convert it to String as it's probably long.
String passc = dataSnapshot.child("passcode").getValue().toString();
Also, just to be sure. Add this line if you haven't already
FirebaseApp.initializeApp(this);
above your
mpasscode=FirebaseDatabase.getInstance().getReference().child("Councilpasscodes");
Hope it helps!
Have you tried using .compareTo() method?
if (passcode1.compareTo(passc) == 0) { }
I think firebase is returning integer instead. You can put the quote to 1234 and try again or compare as integer.
if you are using only numerics then equalsIgnoreCase would do good or if there is no limit of type of character you use in counsilcode then .match would be good
Related
I'm creating my first Android app which is a Tinder clone just for learning purposes.
I'm trying to implement a way to constantly check for changes in the Firebase DB that would work in the background in any activity. e.g. when a user gets a new match and DB is updated, they get a popup notification(in app).
My thinking is maybe there some kind of listener that I need to run in a separate thread and put into every activity? Or just put a DB query in an infinite loop. I don't know what would be the best way.
Sorry if this is a noob question, but I'm kind of stuck and don't know how to move forward with this. Thanks!
In order to achieve what you said, you have to use a ValueEventListener. Try the code below:
DatabaseReference dbref = FirebaseDatabase.getInstance().getReference("Your path");
dbref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnaphsot dataSnaphsot){
//There was a data change so make your pop-up notification.
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError){
}
});
Using the ValueEventListener above, you will be notified everytime there is a change in your Firebase Database path, specified by dbref.
Then, in the onDataChange method, you can get the data that you need, and make the notification.
I had a firebaseAuth and FirebaseDatabse using Android App. I found out some issues with the FirebaseAuth.getInstance().getCurrentUser() returning a previously logged user after I uninstall and re install the app. I posted this issue here
However I also noticed that call to FirebaseDatabse addListenerForSingleValueEvent() callback listener changes some of the data in my database and it only happens when I uninstall and reinstall the app again. shown below is the code I am using to get the current user from the FirebaseDB.
final FirebaseAuth auth = FirebaseAuth.getInstance();
if (auth.getCurrentUser() != null) {
// already signed in
mDatabase.getReference("users").child(auth.getCurrentUser().getUid()).addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// I commented the code here to check whether its coming from this part but it continued to occur even after commenting.
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "getUser:onCancelled", databaseError.toException());
}
});
}
As you can see I am accessing a node called users in the database by using user ID as the key and I am successfully getting the user data. However there is another node named "posts" in my database and I am using the same User IDs as the key. But the users and posts are two different nodes in the database.
So what happens is when the above addListenerForSingleValueEvent() is been called, some of the data under the corresponding user ID in the posts node changes. Right after a few seconds of the callback I can see some new data been removed from users post in red color and some been changed in yellow color.
When I commented the entire callback it was OK nothing changed or removed in posts.
AS I mentioned this only happens when I uninstall and reinstall again. I tried clearing cache without uninstalling and it was OK, I also tried clearing data and it was still OK.
I should also mention that I am using mDatabase.setPersistenceEnabled(true); and this issue only occurs when this is set to true. I tried commenting this line and everything was working fine.
Can anyone please help me as I am lost at this stage.
I am currently working on an app with a friendship feature similar to Facebook(a request is sent and if accepted they both become friends). The sending user can select multiple users from a list and send them all invites at once. When this happens, the receiving users are added to a relation called "pendingRelation" for the sending user. However, I would also like the sending user to be added as a "pendingRelation" for all the receiving users as soon as the request is sent. I have messed around and haven't been able to find a good solution for this. The code to add the selected users as "pendingRelation" is simple.
private boolean sendFriendRequest() {
//Cycles through list of selected friends and adds as "Pending"
for (int i = 0; i < mPendingFriends.size(); i++) { //Cycles through list
mPendingRelation.add(mPendingFriends.get(i));
}
mCurrentUser.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if (e != null) {
Log.e(TAG, e.getMessage());
}
}
});
If anyone can help me add the sender as a "pendingRelation" to the reciever as well to create this two-way relationship that would be great. Thanks!
I've actually thought about making a follow system with Parse which is quite similiar to your problem. Have you thought about making a new ParseObject instead of relation? Then you could add something like ParseUser pendingUser, ParseUser requestUser, boolean isAccepted.
Anywho if you can't find help from here you can try post it to parse.com questions.
I am trying to figure out the same thing for my app (although I am using javascript so I can't give you working code.. sorry.).
To expand on Torsten's answer. One solution would be to create a table(class) in Parse with the fields "pendingFriendRequest" "associatedUserID_requestingUser" "associatedUserID_receivingUser" and "accepted (boolean)".
SIDE NOTE: You could also add a matching function this way by querying
this table(class) and determining whether there are two
"pendingFriendRequests" from each individual user for the other user.
Then, you can present the user the results of querying this table and an option to "accept" (you can also present an option to ignore/delete and just drop the row).
Once the user clicks "accept" link that to a function which then creates the user relation.
In javascript it looks something like this:
likeAUser: function (userId) {
var currentUser = $rootScope.loggedInUser;
var User = Parse.Object.extend("User");
var user = new User();
user.id = userId;
var likes = currentUser.relation("Likes");
//console.log(likes);
likes.add(user);
return currentUser.save();
},
and within the function you are creating the new relation you would then drop(delete) the row from the "pendingRequests" table.
I hope this helps,
I have been racking my brain on how to do this and this is the best way I can figure out pending Parse making it easier to interact with relations elements inside their user class. Sorry I don't know the android version to help more.
In android how do I create a required field validation? like on a page where use can enter some data into some EditText. I wanted to make sure user enter something before continuing, like if the user forgot to enter some data, the app would not crash. I have done other validation like number only using those input-type provided. but so far I research I only found ways to validate content entered but not whether there is something entered.
So I should put something in the onCreate method like
if(EditText text is !=null){ do the stuff} else {error message}
But if I did that, the moment the app is run there will be error displayed.
And how do I write the "text of EditText" in c# I believe is TextBox Text. But I do not know how to do that in java android. I know setText but do not know how to refer to the content without changing it.
To get text user entered in the EditText you can call getText() method. I recommend you to perform validation after user clicks some button. Validating content of EditText inside onCreate() method is useless.
It's always better to tell the user that they need to put the correct information the earliest possible. Why? Because it allows the user to quickly identify the problem and fix it. That being said, I would recommend checking if its null or whatever you want the textfield to contain as soon as it looses focus.
textView.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if(!hasFocus)
//We get the text and then convert it to a string and check
if(v.getText().toString() == ""){
//Do what you want in this area
}
}
});
String str = textview.getText().toString().trim()
Im trying to create a login authentication and when the user enters incorrect password for 3 times.
The texboxes of username and password will be disabled and I'm comparing the user input to my stored username and password in my SQL database to validate the username and password of the user, How can i do this?
you should use a variable that keeps count of attempts. then, when incorrectGuesses equals 3:
editText.setFocusable(false)
or
editText.setEditable(false) // Note that this is deprecated but replacement (inputType) has bug
To set a EditText read only :
Store a reference to your text box (EditText) from your create method and call .setEditable(false) to deactivate them when needed. Maybe you will also call a setText("") on it for clearing the value entered by the user.
There is a relavent issue raised with Google affecting older versions of Android and some random newer devices.
an effecient, reusable, working fix is as follows (assuming this is inside an Activity):
private Static OnClickListener listener;
#Override
public void onCreate(...){
...
listener = new OnClickListener(){ ... };
}
public void disableEditText(EditText t){
t.setOnClickListener(null);
}
public void enableEditText(EditText t){
t.setOnClickListener(listener);
}
issue report for setenabled(false) not working:
http://code.google.com/p/android/issues/detail?id=2771
You should store the number of attempts on SharedPreferences. Once this value reaches 3, just do
editText.setEnabled(false);
You should also check the value of this number in your onCreate or onResume, just so when the user kills the app and restarts it, the EditText will still be disabled.
On another note, you may want to look forward on whether it's a better idea to just disable the OK/Login button (I assume you have that one too) instead of the EditText.