I have a Recycle view set up that it's populated with user's post from Firebase. I would like to implement a feature that allows user's to remove their own post(Similar to Facebook or Instagram). So far I have written some code that allows a post to be removed, but any user have access to remove it.
//This is how my database is set up
Post
-LlISwmjd0pBXzkNHJGW (random push id)
desc: "Used textbook"
id: "Zk32WqxcCHbR1op6j9inFudFJF23"
image: "image link"
name: "user name"
profileimage: "profile image"
//This method allows a post to be removed
//Creates popup and allows user to delete from RecycleView
public void openOptionMenu(View v, final int position) {
PopupMenu popup = new PopupMenu(v.getContext(), v);
popup.getMenuInflater().inflate(R.menu.options_menu, popup.getMenu());
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu1:
Toast.makeText(getApplicationContext(), "Edit clicked", Toast.LENGTH_SHORT).show();
return true;
case R.id.menu2:
FirebaseDatabase.getInstance().getReference().child("Post").child(randomPostKeyId).removeValue();
postList.remove(position);
adapter.notifyDataSetChanged();
return true;
default:
//default intent
return true;
}
}
});
popup.show();
}
You can set Firebase Security rules so that only the owner can modify/delete the post.
Let's say every post has an attribute that contains User Id of the user who created it, if the name of key was ownerId then it would look like this:
{
// Allow anyone to read data, but only authenticated content owners can
// make changes to their data
"rules": {
"Post": {
"${postId}": {
".read": true,
// or ".read": "auth.uid != null" for only authenticated users
".write": "root.child('Post').child(postId).child('ownerId').val() == auth.uid"
}
}
}
}
Check out https://firebase.google.com/docs/rules for complete ddocumentation.
I'm not sure whether I understood your problem correctly. As per my understanding, you want show the delete option for a post if that post is created by the user interacting.
If thats the case, then add a check in the "openOptionMenu" method to see whether the post.name==currentUser.name. If yes, continue with what ever you are doing right now. Else inflate a new options menu with delete option not present.
Related
I have a PreferenceScreen following the docs here and here.
One of the options is a SwitchPreferenceCompat that does some risky work in my app, for example, to send sensitive information periodically. This is the simple switch:
<SwitchPreferenceCompat
app:key="SendInfoToServer"
app:title="Send information on your device to our servers" />
What I need, is to ask the user with a question like this:
This will periodically send sensitive information of
your device to our servers.
Are you sure you want to enable this option?
If the user answer YES then I want the SwitchPreferenceCompat to get activated, otherwise not.
I have investigated a bit a I found this code:
findPreference("SendInfoToServer").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if((boolean) newValue == true){
Toast("Activating this function will safe sensitive information");
}
return true;
}
});
But this message is just a warning message being displayed to the user. What I am trying to achieve is to prompt a question. If the user agrees then the switch should be turned ON, if the user doesn't agree then the switch should remain OFF.
Any ideas on how to do that.
You can modify it using the isChecked method. Here is an example doing that with a popup dialog like you described. This uses the onPreferenceChangeListener, and if the option is being disabled it shows a dialog and returns false for the listener (so the preference not immediately updated).
If the user selects the right option in the dialog then it gets disabled using the isChecked method. The dialog would not be shown if the option is being re-enabled, only when it gets disabled.
Some of the logic might be reversed if you wanted to show the dialog when the option is enabled, but the concept overall is the same. The key is to return false when showing the dialog so it doesn't change, then change it later with isChecked if the user confirms they want to change it.
// replace this with getting the switch if you defined it in the XML
val enableChecks = SwitchPreference(context)
enableChecks.key = Constants.ENABLE_CHECKS
enableChecks.title = getString(R.string.enable_checks)
enableChecks.isPersistent = true
enableChecks.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _, value ->
val disabling = !(value as Boolean)
if( disabling ) {
SimpleDialogs.twoButton(
context,
title = getString(R.string.confirm_disable_check),
message = getString(R.string.confirm_disable_check_msg),
posButton = getString(R.string.disable),
negButton = getString(R.string.cancel),
onPos = {
// user confirmed they want to disable it, set to false
enableChecks.isChecked = false
},
onNeg = {
// user changed their mind, keep it true
enableChecks.isChecked = true
},
icon = SimpleDialogs.ICON_WARNING
)
// return false so the change isn't applied here if showing a dialog
false
}
else {
true
}
}
appearanceCat.addPreference(enableChecks)
Similar answer in Java based on Tyler V answer:
SwitchPreferenceCompat oSwitchPreferenceCompat = findPreference("MyKey");
oSwitchPreferenceCompat.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if((boolean) newValue == false){
return true; //If the check is disabled we do not need to ask the user. In this case we allow the normal flow and let the system disable it. Returning "true" allows the System to disable it.
}
//Here the user is enabling the check, so we prompt to confirm it:
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setMessage("Are you sure you want to enable this?");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
oSwitchPreferenceCompat.setChecked(true);
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
oSwitchPreferenceCompat.setChecked(false);
}
});
builder.setCancelable(false);
Dialog d = builder.create();
d.show();
return false;//returning false we are telling the System to not modify the check yet.
}
});
this is the question Shows the log-in form; the app must generate a message box notifying the user “Please Complete the required field” when the user leave the two text boxes blank ,while clicking the login button; wherein a generated message box pop and notify the user that “Wrong password!” when the user input the correct username and wrong password it will automatically clear the password textbox; wherein the app must generate a message box that notify the user that “Wrong Username!” if the user input the wrong username and correct password it will and automatically clear the username textbox; wherein the app must generate a messages box that notify the user that “Wrong Username and password!” if the user input both wrong username and wrong password it will automatically clear the password and username textboxes and set the text focus to the username textbox; wherein ;the app must notify the user “WELCOME” if when the user input the correct username and password it will automatically close the login activity and open the next activity.
Note: the Username and password must be both “admin”.
Button login;
EditText user, pass;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
user = (EditText)findViewById(R.id.editText1 );
pass = (EditText)findViewById(R.id.editText2 );
login = (Button)findViewById(R.id.button1 );
login.setOnClickListener((OnClickListener) this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.login, menu);
return true;
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(user.equals("admin") && (pass.equals("admin"))){
System.out.println("Welcome!");
Intent intent = new Intent(this, Home.class);
startActivity(intent);
}else if (user.equals(null) && (pass.equals("admin"))) {
System.out.println ("Please Complete Required Field!");
}else if (user.equals("admin") && (pass.equals(null))) {
System.out.println ("Please Complete Required Field!");
}else {
System.out.println ("Wrong Username! or Wrong Password!");
}
}
}
To detect whether the editText is empty or not:
Change (user.equals(null)) to user.getText().toString().trim().length() == 0
and pass.equals(null) to pass.getText().toString().trim().length() == 0
In your button implementation, write like login.setOnClickListener(this); and make sure your Activity/Fragment implement OnClickListener like #pcg26 said.
Make sure you have implemented onClickListener.
In your onClick method, You must use a switch or if statement to make sure that the button is clicked.
Something like this:
public void onClick(View v) {
if(v.getId() == R.id.yourButtonID){
// do here
}
}
Is the activity implementing onclicklistener?
Simple a comment.. You can use Log.e("MyActivity"," the error"); instead System.out.println ^^
I have a DialogFragment that contains AutoCompleteTextView, and Cancel and OK buttons.
The AutoCompleteTextView is giving suggestions of usernames that I'm getting from server.
What I want to do is to restrict the user to be able to enter only existing usernames.
I know I can do check if that username exists when the user clicks OK, but is there some other way, let's say not allow the user to enter character if there doesn't exist such username. I don't know how to do this because on each entered character I'm getting only up to 5 suggestions. The server is implemented that way.
Any suggestions are welcomed.
Thank you
I couldn't find more suitable solution then this:
I added this focus change listener
actName.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
ArrayList<String> results =
((UsersAutoCompleteAdapter) actName.getAdapter()).getAllItems();
if (results.size() == 0 ||
results.indexOf(actName.getText().toString()) == -1) {
actName.setError("Invalid username.");
};
}
}
});
Where the method getAllItems() returns the ArrayList containing the suggestions.
So when I enter some username, and then move to another field this listener is triggered and it checks if the suggestions list is not empty and if the entered username is in that list. If the condition is not satisfied, an error is shown.
Also I have the same check on OK button click:
private boolean checkErrors() {
ArrayList<String> usernameResults =
((UsersAutoCompleteAdapter) actName.getAdapter()).getAllItems();
if (actName.getText().toString().isEmpty()) {
actName.setError("Please enter a username.");
return true;
} else if (usernameResults.size() == 0 || usernameResults.indexOf(actName.getText().toString()) == -1) {
actName.setError("Invalid username.");
return true;
}
return false;
}
So if the AutoComplete view is still focused, the error check is done again.
I have created an activity that refresh quotes when the user clicks a button. Within the same activity there is a check box which the users can click if they like the quote.
Everything works perfectly apart from the check box. When the user clicks they like the quote, I want that check box checked. This only happens when the user moves away from the activity and returns at a later stage.
However when the user stays within the activity and returns to the quote, the old state is shown instead of the users preference.
The check box is configured from the values even in the database, if the value is 1, the check box should be ticked, if not, check box should be clear.
The code is shown below:
When the user clicks the next button, the following code is executed:
Button nextGenerateButton = (Button) findViewById(R.id.btn_next_quotes);
nextGenerateButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
String nextQuote = myDbHelper.getnextQuote();
setQuoteDisplay(nextQuote);
btn_favorite.setChecked(myDbHelper.getFavouriteCheckBoxValue());
}
});
The button retrieves the next quote and the getFavouriteCheckBoxValue() confirms whether the favourite column is marked in the database and either returns a true of false which sets the check box value.
public boolean getFavouriteCheckBoxValue()
{
int laballedFavourite = cursor.getInt(0);
if(laballedFavourite == 0)
{
return false;
}
else
{
return true;
}
}
if the user likes the quote, the code executes the addFavourite() which updates the table where the favourite column will be modified on one.
btn_favorite.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
if(isChecked == true)
{
myDbHelper.addFavourite();
}
if(isChecked == false)
{
myDbHelper.removeFavourite();
}
}
});
public void addFavourite()
{
ContentValues vals = new ContentValues();
vals.put("favouriteQuote", 1);
db.update(TABLE_NAME, vals, "columnId = " + cursor.getInt(1), null);
}
Again this only works perfectly when I resume the quote activity and not when I am currently live in the quote activity.
Hope this makes sense.
Any help would be greatly appreciated.
You need to refresh your checkbox to see the changement because you made a changement in you db but not on the UI. You need to observe the db and refresh the checkbox after a modification.
Refreshing cursor solved the problem.
I am trying to make a donation menu for my app. I have figured out the part that when a user clicks donate, more buttons come up saying how much. Now, I want to be able to have the amount buttons go away if they click the same button again. I want the regular DonateButton to remain. How would I come about doing that?
I have already set it as invisible using purchaseButton.setVisibility(View.GONE);
Here is the code for clicking the button and the other buttons appearing:
public void onClick(View v) {
switch (v.getId()) {
case R.id.DonateButton:
purchaseButton.setVisibility(View.VISIBLE);
purchaseButton2.setVisibility(View.VISIBLE);
purchaseButton3.setVisibility(View.VISIBLE);
case R.id.Donate:
if(BillingHelper.isBillingSupported()){
BillingHelper.requestPurchase(mContext, "donate");
// android.test.purchased or android.test.canceled or android.test.refunded
} else {
Log.i(TAG,"Can't purchase on this device");
}
break;
default:
// nada
Log.i(TAG,"default. ID: "+v.getId());
break;
case R.id.Donatetwo:
if(BillingHelper.isBillingSupported()){
BillingHelper.requestPurchase(mContext, "donate2");
// android.test.purchased or android.test.canceled or android.test.refunded
} else {
Log.i(TAG,"Can't purchase on this device");
}
break;
case R.id.Donatethree:
if(BillingHelper.isBillingSupported()){
BillingHelper.requestPurchase(mContext, "donate3");
// android.test.purchased or android.test.canceled or android.test.refunded
} else {
Log.i(TAG,"Can't purchase on this device");
}
break;
}
}
Screenshot of what I mean:
IMAGE URL (DON'T HAVE 10 REPUTATION YET):
http://i.stack.imgur.com/AMdhS.png
What I am trying to say is.
The app comes up just showing the "Donate!" Button. =>
The user clicks the "Donate!" Button. =>
The buttons "Donate $1", "Donate $3", and "Donate $5" appear. =>
I NEED HELP FROM HERE
A user wants to close the "Donate $1", "Donate $3", and "Donate $5" Buttons. =>
To close them, they click the "Donate!" which was the button they used to open it all. =>
The "Donate $1", "Donate $3", and "Donate $5" go away.
I want it to still allow them to open and close those buttons more than once though.
a simple state variable should do.
put this in your field definition area:
boolean areButtonAmountVisible = false;
and this code as your onClick():
case R.id.DonateButton:
if( areButtonAmountVisible )
{
areButtonAmountVisible = false;
purchaseButton.setVisibility(View.GONE);
purchaseButton2.setVisibility(View.GONE);
purchaseButton3.setVisibility(View.FONE);
}
else
{
areButtonAmountVisible = true;
purchaseButton.setVisibility(View.VISIBLE);
purchaseButton2.setVisibility(View.VISIBLE);
purchaseButton3.setVisibility(View.VISIBLE);
}
Try this.
Use getVisibility() method to know the visible state of button.
int visibility;
visibility = button.getVisibility();
if(visibility == View.VISIBLE) {
button.setVisibility(View.INVISIBLE);
} else {
button.setVisibility(View.VISIBLE);
}
You have to check like this for every button.
I will suggest one more thing.
Take a global variable and use it as notifier, use below code in all button click functions.
boolean again = false;
if (again) {
// make all invisible
again = false;
} else {
// make all visible
again = true;
}