Problem with getting data from Firestore in IntentService - android

Do you know why dataFromDatabase in IntentService code always returns null?
collection.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
dataFromDatabase = documentSnapshot.get("name").toString();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
dataFromDatabase = "Error";
}
});
The user is logged in and userID returns correct value of his ID.
Firestore database looks like this:
Firestore database
This is full code of my IntentService:
public class AppWidgetService extends IntentService {
String dataFromDatabase;
String userID;
public static final String ACTION_FOO = "pl.skawit.challenge.action.FOO";
public AppWidgetService() {
super("AppWidgetService");
}
#Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_FOO.equals(action)) {
handleActionFoo();
}
}
}
private void handleActionFoo() {
FirebaseFirestore firebaseFirestore = FirebaseFirestore.getInstance();
userID = Objects.requireNonNull(FirebaseAuth.getInstance().getCurrentUser()).getUid();
DocumentReference collection = firebaseFirestore.document("users_data/" + userID);
collection.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
dataFromDatabase = documentSnapshot.get("name").toString();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
dataFromDatabase = "Error";
}
});
}

I found a similar post where it says your if documentSnapshot is null and you're sure the document exists, then the problem can be caused by permissions [1].
[1]DocumentSnapshot is always null for a valid document reference

Related

Android Firebase code in custom function return null

this function return message it return null i need solution to return value thanks
public String saveData(final User user) {
final String[] message = new String[1];
firebaseAuth = FirebaseAuth.getInstance();
firebaseAuth.createUserWithEmailAndPassword(user.getEmail().toString(), user.getPassword().toString())
.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(AuthResult authResult) {
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
message[0] = "Fail" + e.getMessage();
}
});
return message[0];
}
The problem is that firebaseAuth.createUserWithEmailAndPassword() is asynchronous operation - so onSuccess() and onFailure() callbacks will be triggered lately in the future. But you will return message[0] immediately after starting operation - that's why you get null result.
To solve that problem you can pass callbacks as arguments to your function and handle result when that callbacks will be triggered. For example,
public void saveData(final User user, OnSuccessListener<AuthResult> success, OnFailureListener failure) {
final String[] message = new String[1];
firebaseAuth = FirebaseAuth.getInstance();
firebaseAuth.createUserWithEmailAndPassword(user.getEmail().toString(), user.getPassword().toString())
.addOnSuccessListener(success).addOnFailureListener(failure);
}
and invoke it
saveData(user, new OnSuccessListener<AuthResult>() {
#Override
public void onSuccess(AuthResult authResult) {
// TODO handle result
}
}, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
String message = "Fail" + e.getMessage();
}
});
Something like that.

read firestore value from document doesn't work

I want to read the a value from firestore document. But it doesn't work for me and I don't know where is the problem.should i use get() or realtime updates.
I tried both but doesn't work for me
this is my code.
I confirmed my positions by using toast and the are ok.
How to solve this problem?
public class SingleAdActivity extends AppCompatActivity {
String x;
String a;
String z;
String coname;
TextView Co_Name;
private ListenerRegistration listenerRegistration;
DocumentReference firebaseFirestore;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_ad);
Co_Name = findViewById(R.id.SingleAd_CoName);
ad_discription = findViewById(R.id.disrcibe_ad);
phone_number = findViewById(R.id.phone);
x = getIntent().getStringExtra("single_ad_position");
a = getIntent().getStringExtra("single_ad_categoryP");
z = getIntent().getStringExtra("documentId");
firebaseFirestore = FirebaseFirestore.getInstance().collection("MainCategories")
.document(String.valueOf(a))
.collection("Ads")
.document(z);
#Override
protected void onStart () {
super.onStart();
listenerRegistration = firebaseFirestore
.addSnapshotListener(this, new EventListener<DocumentSnapshot>() {
#Override
public void
onEvent(#Nullable DocumentSnapshot documentSnapshot, #Nullable FirebaseFirestoreException e) {
if (e != null) {
Toast.makeText(SingleAdActivity.this, "error", Toast.LENGTH_SHORT).show();
return;
}
assert documentSnapshot != null;
if (documentSnapshot.exists()) {
coname = documentSnapshot.getString("CompanyName");
Co_Name.setText(coname);
} else {
// Co_Name.setText(a);
}
}
});
}
#Override
protected void onStop () {
super.onStop();
listenerRegistration.remove();
}
}
}
The way I do it is like this:
FirebaseFirestore firestoreDb = FirebaseFirestore.getInstance();
firestoreDb..collection(yourCollection)
.document(yourDocument)
.get()
.addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if(task.isSuccessful()) {
Object yourObject = task.getResult().toObject(YourClassName.class);
} else {
if(task.getException() != null)
{
task.getException().printStackTrace();
}
}
}
});

FirebaseFirestore insertion

public class Post extends AppCompatActivity {
private static final String TAG = null;
private TextView titleView;
private Button create_post_button;
private EditText post_title,post_description;
private FirebaseAuth mAuth;
private ProgressBar progressBar;
private FirebaseFirestore db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_post);
mAuth=FirebaseAuth.getInstance();
db = FirebaseFirestore.getInstance();
progressBar = (ProgressBar) findViewById(R.id.progressBar2);
titleView=(TextView) findViewById(R.id.titleView);
post_title=(EditText) findViewById(R.id.post_title);
post_description=(EditText) findViewById(R.id.post_description);
create_post_button=(Button)findViewById(R.id.create_post_button);
create_post_button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
createPost();
}
});
}
public void createPost() {
String title_val = post_title.getText().toString().trim();
String post_description_val = post_description.getText().toString().trim();
String user_id=mAuth.getCurrentUser().getUid();
if (!TextUtils.isEmpty(title_val) && !TextUtils.isEmpty(post_description_val)) {
progressBar.setVisibility(View.VISIBLE);
Map<String, String> posts = new HashMap<>();
posts.put("description",post_description_val);
posts.put("title", title_val);
posts.put("user_id", user_id);
progressBar.setVisibility(View.GONE);
db.collection("posts")
.add(posts)
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
#Override
public void onSuccess(DocumentReference documentReference) {
Toast.makeText( Post.this,"Success", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w( TAG,"Error adding document", e);
}});}}}
Its not being inserted into db,neither it gives any error.I don't understand where the error is!I don't know what is wrong since everything is from android main page.If it is some logic error please let me know!
Some help would be appreciated! Thanks in advance!
The problem is because you're accessing the variables wrong when checking for empty title and description, here:
if (!TextUtils.isEmpty(title) && !TextUtils.isEmpty(description_val)) {
it should be:
public void createPost() {
String title_val = title.getText().toString().trim();
String post_description_val = description.getText().toString().trim();
String user_id=mAuth.getCurrentUser().getUid();
if (!title_val.isEmpty() && !post_description_val.isEmpty()) {
progressBar.setVisibility(View.VISIBLE);
Map<String, String> posts = new HashMap<>();
posts.put("description",description_val);
posts.put("title", title);
posts.put("user_id", user_id);
progressBar.setVisibility(View.GONE);
db.collection("posts")
.add(posts)
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
#Override
public void onSuccess(DocumentReference documentReference) {
Toast.makeText( Post.this,"Success", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.w( TAG,"Error adding document", e);
}
});
}
}
EDIT:
For testing purposes your rules should look like this, later you need to update them to make them more secure:

Android Studio Firebase Database return null object reference

Hello Guys i need you I have a problem with Firebase Realtime Database I put the data successful to the Firebase but when I try to retrieve it from Firebase I got a problem there is how I put the data
private void user_info(String user_id, String user_display_name) {
mDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(user_id);
HashMap<String, String> userMap = new HashMap<>();
userMap.put("Name",user_display_name);
userMap.put("Balls","30");
userMap.put("Level","1");
mProgressDialog.setMessage("Please Wait...");
mDatabase.setValue(userMap).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()){
}
else
Toast.makeText(WelcomeActivity.this, ""+task.getException(), Toast.LENGTH_SHORT).show();
mProgressDialog.dismiss();
}
});
}
And how I try to retrieve the data
private FirebaseUser mUser;
private DatabaseReference mDatabase;
private String level,level1;
private int lev,i;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_level_acticity);
//Image
mImg_level1 = (ImageView)findViewById(R.id.mImg_lev1);
mImg_level2 = (ImageView)findViewById(R.id.mImg_lev2);
mImg_level3 = (ImageView)findViewById(R.id.mImg_lev3);
mImg_level4 = (ImageView)findViewById(R.id.mImg_lev4);
mImg_level5 = (ImageView)findViewById(R.id.mImg_lev5);
mImg_level6 = (ImageView)findViewById(R.id.mImg_lev6);
mImg_level7 = (ImageView)findViewById(R.id.mImg_lev7);
mImg_level8 = (ImageView)findViewById(R.id.mImg_lev8);
mImg_level9 = (ImageView)findViewById(R.id.mImg_lev9);
mImg_level10 = (ImageView)findViewById(R.id.mImg_lev10);
mImg_level11 = (ImageView)findViewById(R.id.mImg_lev11);
//Firebase
mUser = FirebaseAuth.getInstance().getCurrentUser();
String user_id = mUser.getUid();
mDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(user_id);
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
level = dataSnapshot.child("Level").getValue().toString();
if (level.equals("1")){
level1 = "1";
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Toast.makeText(this, level1, Toast.LENGTH_SHORT).show();
The toast don't show anything because it null
Change this :-
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
level = dataSnapshot.child("Level").getValue().toString();
if (level.equals("1")){
level1 = "1";
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Toast.makeText(this, level1, Toast.LENGTH_SHORT).show();
to this :-
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
level = dataSnapshot.child("Level").getValue().toString();
if (level.equals("1")){
level1 = "1";
}
Toast.makeText(this, level1, Toast.LENGTH_SHORT).show();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
The reason this works is that Firebase downloads asynchronously and your code lines execute synchronously.

Firebase data not able to get immediately

I don't know why when I try to call getFromRealm() I can't retrieve it on the first time, in order to get the data I have to close and re-open the app.
Am I doing it in the wrong way? I have tried by using Sqlite, but they are having the same problem. Anyone can help?
My goals is to get data immediately and retrieve on the spot.
Below is the code.
MainActivity:
public class MainActivity extends AppCompactActivity {
private static final String TAG = "MainActivity";
public String mName;
public String mEmail;
private Realm mRealm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRealm = Realm.getInstance(this);
mDatabase = FirebaseDatabase.getInstance().getReference();
mAuth = FirebaseAuth.getInstance();
saveToRealm();
getFromRealm();
Log.d(TAG, "Name: " + mName); // Here show null at first open the app
Log.d(TAG, "Email: " + mEmail); // Here show null at first open the app
}
}
This is save data to Realm method:
public void saveToRealm() {
ValueEventListener postListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Users details = dataSnapshot.getValue(Users.class);
Log.d(TAG, String.valueOf(dataSnapshot));
String name = details.getName();
String email = details.getEmail();
details.setName(name);
details.setEmail(email);
mRealm.beginTransaction();
mRealm.copyToRealmOrUpdate(details);
mRealm.commitTransaction();
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "getUser:onCancelled", databaseError.toException());
}
};
mDatabase.child("User")
.child("Details")
.addValueEventListener(postListener);
}
This is the get data method:
public void getFromRealm() {
RealmResults<Users> results =
mRealm.where(Users.class).findAll();
try{
Users c = results.get(0);
mName = c.getName();
mEmail = c.getEmail();
} catch (Exception e) {
Log.e(TAG, String.valueOf(e));
}
}
This is the object class:
public class Users extends RealmObject {
#PrimaryKey
private long id;
private String name;
private String email;
public Users() {
}
public void setId(long id) {
this.id = id;
}
public long getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setEmail(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
}
Retrieve data from where you are store something like this..
public void saveToRealm() {
ValueEventListener postListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Users details = dataSnapshot.getValue(Users.class);
Log.d(TAG, String.valueOf(dataSnapshot));
String name = details.getName();
String email = details.getEmail();
details.setName(name);
details.setEmail(email);
mRealm.beginTransaction();
mRealm.copyToRealmOrUpdate(details);
mRealm.commitTransaction();
getFromRealm();
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w(TAG, "getUser:onCancelled", databaseError.toException());
}
};
mDatabase.child("User")
.child("Details")
.addValueEventListener(postListener);
}
As it will take someTime like seconds to get Data from firebase data so retrieve data after only whenever you store.
Try to get your data like this way..
public void getFromRealm() {
RealmResults<Users> results = mRealm.where(Users.class).findAll();
try {
for(int i=0;i<results.size();i++){
mName = results.get(i).getName();
mEmail = results.get(i).getEmail();
}
} catch (Exception e) {
Log.e(TAG, String.valueOf(e));
}
}

Categories

Resources