Firebase method don't allow a return - java

I have this method looseMoney(...) with a firebase database. Unfortunately the methods onSuccess() and onFailure()
don't allow it to return any value. I want to check if the transaction is succesfull or not? But how could I do that? You can see my code below. What am I missing? I am grateful for every answer. Thank you!
private int looseMoney(String pUserID, final int pAmount) {
final FirebaseFirestore db = FirebaseFirestore.getInstance();
final DocumentReference sfDocRefAbs = db.collection("users").document(pUserID);
db.runTransaction(new Transaction.Function<Void>() {
#Override
public Void apply(Transaction transaction) throws FirebaseFirestoreException {
DocumentSnapshot snapshotAbs = transaction.get(sfDocRefAbs);
int neuerKontostandAbs = 0;
if(pAmount <= (snapshotAbs.getDouble("kontostand"))) {
neuerKontostandAbs = (int) (snapshotAbs.getDouble("kontostand") - pAmount);
transaction.update(sfDocRefAbs, "kontostand", neuerKontostandAbs);
}
else {
//return 1;
}
return null;
}
}).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(getApplicationContext(), "Kontostand erfolgreich angepasst", Toast.LENGTH_SHORT).show();
//return 2;
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getApplicationContext(), "Transaktion fehlgeschlagen: " + e.toString(), Toast.LENGTH_SHORT).show();
//return 3;
}
});
}

We have faced this case and we figured out a simple solution.
First of all you should know that firebase retrieval functions are asynchronous functions. i.e. you will need a call back to be triggered when firebase does it's job.
We have created a simple interface called RetrievalEventListener which provide functions you can call inside the onSuccess event for example.
public interface class RetrievalEventListener<T> {
public abstract void OnDataRetrieved(T t);
}
This interface can be passed as a parameter and you call the onDataRetrieved Function when you want to retrieve the value.
private void looseMoney(String pUserID, final int pAmount, RetrievalEventListener<int> retrievalEventListener) {
final FirebaseFirestore db = FirebaseFirestore.getInstance();
final DocumentReference sfDocRefAbs = db.collection("users").document(pUserID);
db.runTransaction(new Transaction.Function<Void>() {
#Override
public Void apply(Transaction transaction) throws FirebaseFirestoreException {
DocumentSnapshot snapshotAbs = transaction.get(sfDocRefAbs);
int neuerKontostandAbs = 0;
if(pAmount <= (snapshotAbs.getDouble("kontostand"))) {
neuerKontostandAbs = (int) (snapshotAbs.getDouble("kontostand") - pAmount);
transaction.update(sfDocRefAbs, "kontostand", neuerKontostandAbs);
}
else {
//return 1;
retrievalEventListener.onDataRetrieved(1);
}
return null;
}
}).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(getApplicationContext(), "Kontostand erfolgreich angepasst", Toast.LENGTH_SHORT).show();
retrievalEventListener.onDataRetrieved(2);
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getApplicationContext(), "Transaktion fehlgeschlagen: " + e.toString(), Toast.LENGTH_SHORT).show();
//return 3;
retrievalEventListener.onDataRetrieved(3);
}
});
}
How should you call the function?
It should like this:
String pUserID = "someId";
int pAmount = 10;
looseMoney(pUserID, pAmount, new RetrievalEventListener<int>() {
#Override
public void OnDataRetrieved(int number) {
// Now you have the required number do what do you need with it
}
});
If you want more clarifications let me know :)

Related

Selecting in RecyclerView and delete from firebase in java

I want to delete my document from firebase. But first I need to determine the document id. I tried to get document id:
docId = queryDocumentSnapshots.getDocuments().get(pos).getId();
Then, I just wanted to delete my document. But firebase works async so code doesnt work in 'if' statement. When we first click the button, docId variable is null or it takes the docId which was clicked before till the async code part done.
#Override
public void onBindViewHolder(#NonNull AdvertisementHolder holder, int position) {
imgUrl = publishedAdvertisements.get(position).getImgUrl();
holder.petName.setText(publishedAdvertisements.get(position).getPetName());
holder.petCategory.setText(publishedAdvertisements.get(position).getPetCategory());
Picasso.get().load(publishedAdvertisements.get(position).getImgUrl()).into(holder.petImage);
holder.btnDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
firebaseFirestore = FirebaseFirestore.getInstance();
firebaseFirestore.collection("Pets").get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(#NonNull QuerySnapshot queryDocumentSnapshots) {
if (!queryDocumentSnapshots.isEmpty()) {
System.out.println("bos döndü");
docId = queryDocumentSnapshots.getDocuments().get(pos).getId();
}
}
});
System.out.println(docId);
if (docId != null) {
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collection("Pets").document(docId)
.delete()
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "DocumentSnapshot successfully deleted!");
publishedAdvertisements.clear();
getPublishedAnimals();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Error deleting document", e);
}
});
}
notifyDataSetChanged();
}
});
You should structure your code so that any logic that depends on your asynchronous operation is executed or triggered within the response callback.
You can do something like this:
#Override
public void onBindViewHolder(#NonNull AdvertisementHolder holder, int position) {
imgUrl = publishedAdvertisements.get(position).getImgUrl();
holder.petName.setText(publishedAdvertisements.get(position).getPetName());
holder.petCategory.setText(publishedAdvertisements.get(position).getPetCategory());
Picasso.get().load(publishedAdvertisements.get(position).getImgUrl()).into(holder.petImage);
holder.btnDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
firebaseFirestore = FirebaseFirestore.getInstance();
firebaseFirestore.collection("Pets").get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(#NonNull QuerySnapshot queryDocumentSnapshots) {
// The asynchronous operation has successfully completed
// and returned a value to our 'onSuccess()' callback.
if (!queryDocumentSnapshots.isEmpty()) {
System.out.println("bos döndü");
docId = queryDocumentSnapshots.getDocuments().get(pos).getId();
System.out.println(docId);
// We can now use the value of docId.
if (docId != null) {
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collection("Pets").document(docId)
.delete()
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "DocumentSnapshot successfully deleted!");
publishedAdvertisements.clear();
getPublishedAnimals();
// (1)
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w(TAG, "Error deleting document", e);
}
});
}
// I'm not sure how your RecyclerView is set up
// but I'm guessing you might want to move this call
// to 'notifyDataSetChanged()' to the section marked (1)
notifyDataSetChanged();
}
}
});
}
});
}

method int return wrong value [duplicate]

This question already has answers here:
How do i use a variable outside the onResponse in Android?
(4 answers)
Closed 4 years ago.
Greeting all, I am having the hard time to set int value for a variable in ValueEventListener and get that value outside ValueEventListener for the method to checking is value == 1, the method will return 1, else return 0
I have tried many way like save the value via SharedPreferences, set value to Textview and call from textview, but still, the method always return 0 as it cannot read the value that have been set in ValueEventListener. Any help are much appreciate. Thank you
Here my code
int status = 0;
protected void onCreate(Bundle savedInstanceState) {
...
btnSync_in.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (getCustomerList() == 1) {
msg = msg + "Get customer success \n";
} else {
msg = msg + "Get customer unsuccessful \n";
}
AlertDialog.Builder statusDialog = new AlertDialog.Builder(SyncActivity.this);
statusDialog.setPositiveButton("OK", null);
statusDialog.setTitle("Status");
statusDialog.setMessage(msg);
statusDialog.show();
msg = "";
}
});
}
The method that will return the int
private int getCustomerList() {
urlRef = myRef.child("...");
urlRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
...
StringRequest stringRequest = new StringRequest(Request.Method.GET, customerURL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
status = 1; //here my problem, value assign here is success
try {
...
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
...
status = 0; // here if unsuccessful
}
});
RequestQueue requestQueue = Volley.newRequestQueue(SyncActivity.this);
requestQueue.add(stringRequest);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
...
}
});
if (status == 1) {
return 1;
} else {
return 0;
}
}
Even better way why dont't you display your AlertDialog inside getCustomerList() method
Call your getCustomerList() like this
btnSync_in.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getCustomerList();
}
});
Then add your AlertDialog inside getCustomerList() like this
SAMPLE CODE
private void getCustomerList() {
AlertDialog.Builder statusDialog = new AlertDialog.Builder(SyncActivity.this);
statusDialog.setPositiveButton("OK", null);
statusDialog.setTitle("Status");
urlRef = myRef.child("...");
urlRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
...
StringRequest stringRequest = new StringRequest(Request.Method.GET, customerURL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
msg = msg + "Get customer success \n";
statusDialog.setMessage(msg);
statusDialog.show();
msg = "";
try {
...
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
...
msg = msg + "Get customer unsuccessful \n";
statusDialog.setMessage(msg);
statusDialog.show();
msg = "";
}
});
RequestQueue requestQueue = Volley.newRequestQueue(SyncActivity.this);
requestQueue.add(stringRequest);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
...
}
});
}

Room LiveData onChange called too fast. Many Activities stacked atop

#Dao
public interface LibraryCoverContentDao {
#Query("SELECT * FROM LibraryCoverContent where rush_id = :rush_id")
LiveData<List<LibraryCoverContent>> getContentsFromRushID(String rush_id);
#Query("DELETE FROM library_cover where rush_id = :rush_id")
void deleteContentsFromRushID(String rush_id);
#Insert(onConflict = REPLACE)
void insertCoverContents(LibraryCoverContent... contents);
}
I want to open another activity once a list LiveData> mLibraryCoverContents is not null.
I am inserting the items downloaded from a retrofit call one by one into the room database, so apparently, my startActivity() call for the next activity happens many a times and multiple-same activities are opened over this activity.
I want only a single activity on top by calling onChanged only after all items of the retrofit call are inserted into db.
Please see the following related code for reference:
public void openReadRushScreen(final int index) {
int count = mCoversList.size();
if(count > index){
mRushIDContent = mLibraryContentRepository.getContentsFromID(mCoversList.get(index).getRush_id());
mRushIDContent.observe(this, new Observer<List<LibraryCoverContent>>() {
#Override
public void onChanged(#Nullable List<LibraryCoverContent> libraryCoverContents) {
Toast.makeText(getActivity(), "ON CHANGED", Toast.LENGTH_SHORT).show();
if(libraryCoverContents!=null && libraryCoverContents.size()>0){
mRushIDContentsList = libraryCoverContents;
if(mRushIDContentsList.size()>0 && mRushIDContentsList.get(0).getRush_id().equals(mCoversList.get(index).getRush_id())){
mRushIDContentsList = new ArrayList<>();
startActivity(ReadRushActivity.getStartIntent(getActivity(), mCoversList.get(index).getRush_id(),
mCoversList.get(index).isRush_audio(),
mCoversList.get(index).getTitle()));
}
}
else {
if(mCoversList!=null && mCoversList.size()>index) getContent(mCoversList.get(index).getRush_id());
}
}
});
}
else Toast.makeText(getActivity(), "Empty Cover", Toast.LENGTH_SHORT).show();
}
public void getContent(String mRushId) {
mApiService = ApiClient.getClient().create(ApiInterface.class);
Call<List<Content>> call = mApiService.getRushContent(mRushId);
if(call!=null){
call.enqueue(new Callback<List<Content>>() {
#Override
public void onResponse(#NonNull Call<List<Content>> call, #NonNull Response<List<Content>> response) {
mContents = response.body();
if(mContents!=null && mContents.size()>0){
//noinspection ConstantConditions
List<LibraryCoverContent> coverContent = new ArrayList<>();
for(int i=0; i<mContents.size(); i++){
coverContent.add(new LibraryCoverContent
(mContents.get(i).getContent_id(), mContents.get(i).getRush_id(),
mContents.get(i).getContent(), mContents.get(i).getAttr(),
mContents.get(i).getDatetime(), mContents.get(i).getPage_no()));
}
mLibraryContentRepository.insertContentItems(coverContent);
}
}
#Override
public void onFailure(#NonNull Call<List<Content>> call, #NonNull Throwable t) {
// if(getActivity()!=null) Toast.makeText(getActivity(), "Network Error while downloading rush content", Toast.LENGTH_LONG).show();
}
});
}
}
#SuppressLint("StaticFieldLeak")
public void insertContentItems(final List<LibraryCoverContent> items) {
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... voids) {
for(int i=0; i<items.size(); i++){
mLibraryCoverContentDao.insertCoverContents(items.get(i));
}
return null;
}
}.execute();
}

Firebase Firestore get data from collection

I want to get data from my Firebase Firestore database. I have a collection called user and every user has collection of some objects of the same type (My Java custom object). I want to fill my ArrayList with these objects when my Activity is created.
private static ArrayList<Type> mArrayList = new ArrayList<>();;
In onCreate():
getListItems();
Log.d(TAG, "onCreate: LIST IN ONCREATE = " + mArrayList);
*// it logs empty list here
Method called to get items to list:
private void getListItems() {
mFirebaseFirestore.collection("some collection").get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot documentSnapshots) {
if (documentSnapshots.isEmpty()) {
Log.d(TAG, "onSuccess: LIST EMPTY");
return;
} else {
for (DocumentSnapshot documentSnapshot : documentSnapshots) {
if (documentSnapshot.exists()) {
Log.d(TAG, "onSuccess: DOCUMENT" + documentSnapshot.getId() + " ; " + documentSnapshot.getData());
DocumentReference documentReference1 = FirebaseFirestore.getInstance().document("some path");
documentReference1.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
Type type= documentSnapshot.toObject(Type.class);
Log.d(TAG, "onSuccess: " + type.toString());
mArrayList.add(type);
Log.d(TAG, "onSuccess: " + mArrayList);
/* these logs here display correct data but when
I log it in onCreate() method it's empty*/
}
});
}
}
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getApplicationContext(), "Error getting data!!!", Toast.LENGTH_LONG).show();
}
});
}
The get() operation returns a Task<> which means it is an asynchronous operation. Calling getListItems() only starts the operation, it does not wait for it to complete, that's why you have to add success and failure listeners.
Although there's not much you can do about the async nature of the operation, you can simplify your code as follows:
private void getListItems() {
mFirebaseFirestore.collection("some collection").get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot documentSnapshots) {
if (documentSnapshots.isEmpty()) {
Log.d(TAG, "onSuccess: LIST EMPTY");
return;
} else {
// Convert the whole Query Snapshot to a list
// of objects directly! No need to fetch each
// document.
List<Type> types = documentSnapshots.toObjects(Type.class);
// Add all to your list
mArrayList.addAll(types);
Log.d(TAG, "onSuccess: " + mArrayList);
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getApplicationContext(), "Error getting data!!!", Toast.LENGTH_LONG).show();
}
});
}
Try this..Working fine.Below function will get Realtime Updates from firebse as well..
db = FirebaseFirestore.getInstance();
db.collection("dynamic_menu").addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
if (e !=null)
{
}
for (DocumentChange documentChange : documentSnapshots.getDocumentChanges())
{
String isAttendance = documentChange.getDocument().getData().get("Attendance").toString();
String isCalender = documentChange.getDocument().getData().get("Calender").toString();
String isEnablelocation = documentChange.getDocument().getData().get("Enable Location").toString();
}
}
});
More reference
:https://firebase.google.com/docs/firestore/query-data/listen
If You do not want realtime updates refer Below Document
https://firebase.google.com/docs/firestore/query-data/get-data
Here is a simplified example:
Create a collection "DownloadInfo" in Firebase.
And add a few documents with these fields inside it:
file_name (string),
id (string),
size (number)
Create your class:
public class DownloadInfo {
public String file_name;
public String id;
public Integer size;
}
Code to get list of objects:
FirebaseFirestore db = FirebaseFirestore.getInstance();
db.collection("DownloadInfo")
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
if (task.getResult() != null) {
List<DownloadInfo> downloadInfoList = task.getResult().toObjects(DownloadInfo.class);
for (DownloadInfo downloadInfo : downloadInfoList) {
doSomething(downloadInfo.file_name, downloadInfo.id, downloadInfo.size);
}
}
}
} else {
Log.w(TAG, "Error getting documents.", task.getException());
}
}
});
db.collection("users").get().then((querySnapshot) => {
querySnapshot.forEach((doc) => {
console.log(`${doc.id} => ${doc.data()}`);
});
source:-
https://firebase.google.com/docs/firestore/quickstart
This is the code to get the list.
Since this is an async task, it takes time that's why the list size shows empty at first.
But including the source for the cache data will enable the previous list(and also its size) to be in memory until next task is performed.
Source source = Source.CACHE;
firebaseFirestore
.collection("collectionname")
.get(source)
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot documentSnapshots) {
if (documentSnapshots.isEmpty()) {
return;
} else {
// Convert the whole Query Snapshot to a list
// of objects directly! No need to fetch each
// document.
List<ModelClass> types = documentSnapshots.toObjects(ModelClass.class);
// Add all to your list
mArrayList.addAll(types);
}
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
}
});

Correct code location to check Firebase if a user has been created already?

I've created a method to take a users facebook data, after they login, and create a "user" for them on my firebase database. this method, addUser(), also creates and sets the variables for said user. But I have to leave the method in, login, so it creates my variables, then comment the method out for future testing, or it will reset all the values.
So where can I add "addUser()" to create said user the first time, and make sure it never call it again, as long as the user already exists?
The MainActivity (start and login)
public class MainActivity extends AppCompatActivity {
CallbackManager callbackManager;
ShareDialog shareDialog;
LoginButton login;
ProfilePictureView profile;
Dialog details_dialog;
TextView details_txt;
JSONObject response;
/* Used to track user logging in/out off Facebook */
private AccessTokenTracker mFacebookAccessTokenTracker;
/* A reference to the Firebase */
private Firebase mFirebaseRef;
/* A reference to the Firebase */
private Firebase userRef;
/* Data from the authenticated user */
public static AuthData mAuthData;
/* Listener for Firebase session changes */
private Firebase.AuthStateListener mAuthStateListener;
public static String uName = null;
public static String uEmail = null;
public static String uUrl = null;
public static int mTokens = 50;
public static String uID = null;
public static int getLiveTokens() {
return liveTokens;
}
public static void setLiveTokens(int liveTokens) {
MainActivity.liveTokens = liveTokens;
}
public static int liveTokens = 0;
public static int getLiveSpins() {
return liveSpins;
}
public static void setLiveSpins(int liveSpins) {
MainActivity.liveSpins = liveSpins;
}
public static int liveSpins = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFirebaseRef = new Firebase("https://<url>.firebaseio.com/");
callbackManager = CallbackManager.Factory.create();
login = (LoginButton) findViewById(R.id.login_button);
profile = (ProfilePictureView) findViewById(R.id.picture);
shareDialog = new ShareDialog(this);
login.setReadPermissions("public_profile email");
details_dialog = new Dialog(this);
details_dialog.setContentView(R.layout.dialog_details);
details_dialog.setTitle("Details");
details_txt = (TextView) details_dialog.findViewById(R.id.details);
getLoginDetails(login);
mFacebookAccessTokenTracker = new AccessTokenTracker() {
#Override
protected void onCurrentAccessTokenChanged(AccessToken oldAccessToken, AccessToken currentAccessToken) {
//Log.i(Tag, "Facebook.AccessTokenTracker.OnCurrentAccessTokenChanged");
// Toast.makeText(getApplicationContext(), "FBAccessTokenChange", Toast.LENGTH_LONG).show();
MainActivity.this.onFacebookAccessTokenChange(currentAccessToken);
}
};
if (AccessToken.getCurrentAccessToken() != null) {
RequestData();
getLoginDetails(login);
getUserInfo();
Toast.makeText(getApplicationContext(), "Already Logged In", Toast.LENGTH_LONG).show();
}
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (AccessToken.getCurrentAccessToken() != null) {
profile.setProfileId(null);
}
}
});
mAuthStateListener = new Firebase.AuthStateListener() {
#Override
public void onAuthStateChanged(AuthData authData) {
// mAuthProgressDialog.hide();
setAuthenticatedUser(authData);
}
};
/* Check if the user is authenticated with Firebase already. If this is the case we can set the authenticated
* user and hide hide any login buttons */
mFirebaseRef.addAuthStateListener(mAuthStateListener);
}
public void addUser() {
this.uID = mAuthData.getUid();
Toast.makeText(getApplicationContext(), "Setting Up User Account", Toast.LENGTH_LONG).show();
Firebase rootRef = new Firebase("https://<url>.firebaseio.com/users/");
Firebase userRef = rootRef.child(mAuthData.getUid() + "/");
userRef.child("name").setValue(mAuthData.getProviderData().get("displayName"));
userRef.child("provider").setValue(mAuthData.getProvider());
userRef.child("email").setValue(mAuthData.getProviderData().get("email"));
userRef.child("tokens").setValue("100");
userRef.child("spins").setValue("100");
userRef.child("totalspins").setValue("0");
userRef.child("topwin").setValue("0");
}
protected void getLoginDetails(LoginButton login){
login.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
#Override
public void onSuccess(LoginResult login_Result) {
getUserInfo();
}
#Override
public void onCancel() {
}
#Override
public void onError(FacebookException exception) {
}
});
}
// LoginResult login_result
protected void getUserInfo() {
// LoginResult login_result.getAccessToken()
GraphRequest data_request = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject json_object, GraphResponse response) {
Intent intent = new Intent(MainActivity.this, HomeActivity.class);
intent.putExtra("jsondata", json_object.toString());
intent.putExtra("Uid", uID);
startActivity(intent);
}
});
Bundle permission_param = new Bundle();
permission_param.putString("fields", "id,name,email,picture.width(120).height(120)");
data_request.setParameters(permission_param);
data_request.executeAsync();
}
public void RequestData() {
GraphRequest request = GraphRequest.newMeRequest(AccessToken.getCurrentAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
JSONObject json = response.getJSONObject();
try {
if (json != null) {
String text = "<b>Name :</b> " + json.getString("name") + "<br><br><b>Email :</b> " + json.getString("email") + "<br><br><b>Profile link :</b> " + json.getString("link");
details_txt.setText(Html.fromHtml(text));
profile.setProfileId(json.getString("id"));
uName = json.getString("name");
uEmail = json.getString("email");
uUrl = json.getString("id");
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,link,email,picture");
request.setParameters(parameters);
request.executeAsync();
}
/**
* This method will attempt to authenticate a user to firebase given an oauth_token (and other
* necessary parameters depending on the provider)
*/
private void authWithFirebase(final String provider, Map<String, String> options) {
if (options.containsKey("error")) {
showErrorDialog(options.get("error"));
} else {
//mAuthProgressDialog.show();
// if the provider is not twitter, we just need to pass in the oauth_token
mFirebaseRef.authWithOAuthToken(provider, options.get("oauth_token"), new AuthResultHandler(provider));
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
callbackManager.onActivityResult(requestCode, resultCode, data);
}
private void setAuthenticatedUser(AuthData authData) {
if (authData != null) {
/* show a provider specific status text */
String name = null;
if (authData.getProvider().equals("facebook")) {
name = (String) authData.getProviderData().get("displayName");
} else if (authData.getProvider().equals("anonymous")
|| authData.getProvider().equals("password")) {
name = authData.getUid();
} else {
Toast.makeText(getApplicationContext(), "invalid provider", Toast.LENGTH_LONG).show();
}
if (name != null) {
//success
// Toast.makeText(getApplicationContext(), "Log " + name + " (" + authData.getProvider() + ")", Toast.LENGTH_LONG).show();
}
} else {
}
// Firebase Authenticated
this.mAuthData = authData;
MainActivity.uID = mAuthData.getUid();
//addUser();
/* invalidate options menu to hide/show the logout button */
supportInvalidateOptionsMenu();
}
/**
* Show errors to users
*/
private void showErrorDialog(String message) {
new AlertDialog.Builder(this)
.setTitle("Error")
.setMessage(message)
.setPositiveButton(android.R.string.ok, null)
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
}
private class AuthResultHandler implements Firebase.AuthResultHandler {
private final String provider;
public AuthResultHandler(String provider) {
this.provider = provider;
}
#Override
public void onAuthenticated(AuthData authData) {
// mAuthProgressDialog.hide();
// Toast.makeText(getApplicationContext(), "Auth Success", Toast.LENGTH_LONG).show();
// Toast.makeText(getApplicationContext(), authData.getUid(), Toast.LENGTH_LONG).show();
// createUser();
setAuthenticatedUser(authData);
String mEmail = authData.getUid();
// uID = authData.getUid();
String mProvide = mAuthData.getProvider();
}
#Override
public void onAuthenticationError(FirebaseError firebaseError) {
//mAuthProgressDialog.hide();
showErrorDialog(firebaseError.toString());
}
}
public void createUser(){
Firebase rootRef = new Firebase("https://<url>.firebaseio.com/");
Firebase userRef = rootRef.child("users").child(mAuthData.getUid());
userRef.child("provider").setValue(mAuthData.getProvider());
userRef.child("provider").setValue(mAuthData.getProviderData().get("displayName)"));
rootRef.createUser(mAuthData.getProviderData().get("email").toString(), mAuthData.getProviderData().get("id").toString(), new Firebase.ValueResultHandler<Map<String, Object>>() {
#Override
public void onSuccess(Map<String, Object> result){
Toast.makeText(getApplicationContext(), "Yes-UID=" + result.get("Uid") , Toast.LENGTH_LONG).show();
}
#Override
public void onError(FirebaseError firebaseError){
Toast.makeText(getApplicationContext(), "Not Created", Toast.LENGTH_LONG).show();
}
});
}
private void logout() {
if (this.mAuthData != null) {
/* logout of Firebase */
mFirebaseRef.unauth();
/* Logout of any of the Frameworks. This step is optional, but ensures the user is not logged into
* Facebook/Google+ after logging out of Firebase. */
if (this.mAuthData.getProvider().equals("facebook")) {
/* Logout from Facebook */
LoginManager.getInstance().logOut();
}
/* Update authenticated user and show login buttons */
setAuthenticatedUser(null);
}
}
#Override
protected void onResume() {
super.onResume();
AppEventsLogger.activateApp(this);
}
#Override
protected void onPause() {
super.onPause();
AppEventsLogger.deactivateApp(this);
}
/* ************************************
* FACEBOOK *
**************************************
*/
private void onFacebookAccessTokenChange(AccessToken token) {
if (token != null) {
//mAuthProgressDialog.show();
mFirebaseRef.authWithOAuthToken("facebook", token.getToken(), new AuthResultHandler("facebook"));
} else {
// Logged out of Facebook and currently authenticated with Firebase using Facebook, so do a logout
if (this.mAuthData != null && this.mAuthData.getProvider().equals("facebook")) {
mFirebaseRef.unauth();
setAuthenticatedUser(null);
}
}
}
public static int getmTokens() {
return getLiveTokens();
}
public static void setmTokens(int mTokens) {
MainActivity.mTokens = mTokens;
}
public static void takemTokens(int mTokens) {
MainActivity.mTokens -= mTokens;
}
public static void givemTokens(final int ttokens) {
//MainActivity.mTokens += tokens;
// TODO
// if (ttokens > MainActivity.getmTopWin()){
// MainActivity.setmTopWin(ttokens);
//}
Firebase ref = new Firebase("https://<url>.firebaseio.com/users/" + MainActivity.uID + "/");
final Firebase tokensRef = ref.child("tokens");
tokensRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int iii = new Integer(dataSnapshot.getValue().toString());
iii += ttokens;
tokensRef.setValue(iii);
setLiveTokens(iii);
checkmTopWin(ttokens);
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
//tokensRef.removeEventListener(MainActivity);
}
public static int mSpins = 30;
public static int getmSpins() {
return getLiveSpins();
}
public static void setmSpins(int mspins) {
MainActivity.mSpins = mspins;
}
public static void takemSpins(final int mspins) {
Firebase ref = new Firebase("https://<url>.firebaseio.com/users/" + MainActivity.uID + "/");
final Firebase tokensRef = ref.child("spins");
tokensRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int i = Integer.valueOf(dataSnapshot.getValue().toString());
i -= mspins;
tokensRef.setValue(i);
setLiveSpins(i);
}
#Override
public void onCancelled(FirebaseError firebaseError) {}
});
}
public static void givemSpins(final int mspins){
Firebase ref = new Firebase("https://<url>.firebaseio.com/users/" + MainActivity.uID + "/");
final Firebase tokensRef = ref.child("spins");
tokensRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int i = Integer.valueOf(dataSnapshot.getValue().toString());
i += mspins;
tokensRef.setValue(i);
}
#Override
public void onCancelled(FirebaseError firebaseError) {}
});
}
public static int slotVari = 0;
public static int getSlotVari() {
return slotVari;
}
public static void setSlotVari(int slotVari) {
MainActivity.slotVari = slotVari;
}
public static int mTotalSpins;
public static int getmTotalSpins() {
return mTotalSpins;
}
public static void setmTotalSpins(int mTotalSpins) {
MainActivity.mTotalSpins = mTotalSpins;
}
public static void incmTotalSpins(){
Firebase ref = new Firebase("https://<url>.firebaseio.com/users/" + MainActivity.uID + "/");
final Firebase tokensRef = ref.child("totalspins");
tokensRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int i = Integer.valueOf(dataSnapshot.getValue().toString());
i++;
tokensRef.setValue(i);
}
#Override
public void onCancelled(FirebaseError firebaseError) {}
});
MainActivity.mTotalSpins++;
}
public static int mTopWin;
public static int getmTopWin() {
return mTopWin;
}
public static void setmTopWin(int mTopWin) {
Firebase ref = new Firebase("https://<url>.firebaseio.com/users/" + MainActivity.uID + "/");
Firebase tokensRef = ref.child("topwin");
tokensRef.setValue(mTopWin);
MainActivity.mTopWin = mTopWin;
}
public static void checkmTopWin(final int mTokensWon) {
Firebase ref = new Firebase("https://<url>.firebaseio.com/users/" + MainActivity.uID + "/");
final Firebase tokensRef = ref.child("topwin");
tokensRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int i = Integer.valueOf(dataSnapshot.getValue().toString());
if (i < mTokensWon){
tokensRef.setValue(mTokensWon);
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {}
});
}
}
You need to set a preference like FIRST_LAUNCH and check if its true each time your user logs in. First time the application launches, the FIRST_LAUNCH preference won't be found. So call your addUser() function to create a new entry in your FireBase database.
SharedPreferences pref = getSharedPreferences(Constants.ApplicationTag, Activity.MODE_PRIVATE);
if (!pref.contains(Constants.FIRST_LAUNCH)) {
addUser();
pref.edit().putBoolean(Constants.FIRST_LAUNCH, true).commit();
}
So you might be thinking of if an user uninstalls your application and then reinstalls it, the preferences will be gone and the addUser() function will be called again. No problem, you won't get a new Firebase entry as long as the path to the child attribute is the same. The values will be replaced to the specific path (if it does exist), with current information of user.
Now if you want to check if your user already exists in Firebase database you need to add a listener like this. I'm attaching a code sample for better understanding.
Firebase rootRef = new Firebase("https://<url>.firebaseio.com/users/");
Firebase userRef = rootRef.child(mAuthData.getUid() + "/");
userRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
// User exists. Do nothing
} else addUser();
}
#Override
public void onCancelled(FirebaseError firebaseError) {}
});

Categories