In my app users are able to send text and images to other users and now i also want when a user clicks on the sent or received image they will be taken to another activity were the image will be loaded into an image view for the user.
So i added a click listener to the image in my adapter like this
void bind(Messages message) {
String message_type = message.getType();
String user_id = message.getFrom();
String msg_id = message.getKey();
if (message_type.equals("text")) {
messageText.setText(message.getMessage());
// Format the stored timestamp into a readable String using method.
timeText.setText(DateUtils.formatDateTime(message.getTime()));
// DatabaseReference messageRef = mRootRef.child("messages").child(mCurrentUserId).child(user_id).child()
recieved_image.setVisibility(View.INVISIBLE);
// nameText.setText(message.getSender().getNickname());
// Insert the profile image from the URL into the ImageView.
// Utils.displayRoundImageFromUrl(mContext, message.getSender().getProfileUrl(), profileImage);
}else {
messageText.setVisibility(View.INVISIBLE);
recieved_image.setVisibility(View.VISIBLE);
Picasso.with(recieved_image.getContext()).load(message.getMessage()).into(recieved_image);
recieved_image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), MessageImageViewerActivity.class);
intent.putExtra("message_id",msg_id);
view.getContext().startActivity(intent);
}
});
with the aim of transferring the message id to the next activity which should be used to locate and load the image from firebase storage like this
msgImage = findViewById(R.id.MsgImageView);
mAuth = FirebaseAuth.getInstance();
final String message_id = getIntent().getStringExtra("message_id");
mRootRef = FirebaseDatabase.getInstance().getReference();
mCurrentUserId = mAuth.getCurrentUser().getUid();
mImageStorage.child("message_images").child(message_id).getDownloadUrl().addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()){
String ima = task.getResult().toString();
// Picasso.with(MessageImageViewerActivity.this).load(ima).into(msgImage);
Glide.with(MessageImageViewerActivity.this)
.load(ima)
.into(msgImage);
}
}
});
but it is returning an error that the path is invalid. this is the logcat error message.
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.firebase.storage.StorageReference com.google.firebase.storage.StorageReference.child(java.lang.String)' on a null object reference
at com.mani.eric.quickchat.ui.MessageImageViewerActivity.onCreate(MessageImageViewerActivity.java:60)
at android.app.Activity.performCreate(Activity.java:7327)
at android.app.Activity.performCreate(Activity.java:7318)
please what I'm trying to do, is it possible?
or what I'm i not doing right.
You need to do the following:
StorageReference mImageStorage = FirebaseStorage.getInstance().getReference();
First get the reference to the firebase storage, then access the child that you created in the firebase storage console.
mImageStorage.child("message_images").child(message_id).getDownloadUrl().addOnCompleteListener(new OnCompleteListener<Uri>() {
#Override
public void onComplete(#NonNull Task<Uri> task) {
if (task.isSuccessful()){
String ima = task.getResult().toString();
// Picasso.with(MessageImageViewerActivity.this).load(ima).into(msgImage);
Glide.with(MessageImageViewerActivity.this)
.load(ima)
.into(msgImage);
}
}
});
Related
suggest collectionusers collectionI have a simple suggestion page where I can type title and contents, then store some other information to the Firestore, show it on ListView pages. It works fine itself, but after I send it, an error pops and it shows the bug is the timestamp toDate on the listview pages
The order of activities is listview>sending page>listview.
//the send activity
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
v.getId();
String title = art1.getText().toString();
String content = art2.getText().toString();
Intent intent = new Intent(create_announce_main.this, SuggestionMain.class);
// DocumentReference documentReference = firebaseFirestore.collection("announce").document("ann");
Map<String, Object> suggest = new HashMap<>();
suggest.put("title", title);
suggest.put("content", content);
suggest.put("name", name);
suggest.put("recID", recID);
suggest.put("admin_name", "");
suggest.put("response_content", "");
suggest.put("response_status", "未回覆");
suggest.put("response_time",FieldValue.serverTimestamp());
suggest.put("createdAt", FieldValue.serverTimestamp());
firebaseFirestore.collection("Suggestion").document().set(suggest).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(create_announce_main.this, "added succesfully", Toast.LENGTH_LONG).show();
}
}
});
startActivity(intent);
}
});
to listview page
//the view
DocumentReference docRef = firebaseFirestore.collection("users").document(userID);
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
Log.d("TAG", "DocumentSnapshot data: " + document.getData());
recID = document.getString("recID");
firebaseFirestore.collection("Suggestion").whereEqualTo("recID",recID).orderBy("createdAt", Query.Direction.DESCENDING).addSnapshotListener((documentSnapshots, error) -> {
ar.clear();
for (DocumentSnapshot snapshot : documentSnapshots){
idlv = snapshot.getId();
Timestamp timestamp = (Timestamp) snapshot.getData().get("createdAt");
**Date date = timestamp.toDate();//the error is at here**
String date2 = date.toString();
ar.add(new itemAnnounce(R.drawable.notes, snapshot.getString("title"),"回饋於 "+date2,"回覆管理者:"+snapshot.getString("admin_name"),"回覆狀態:"+snapshot.getString("response_status"),idlv,url));
}
adapterAnnounce adapterAnnounce = new adapterAnnounce(getApplicationContext(), R.layout.list_row_announce, ar);
adapterAnnounce.notifyDataSetChanged();
lv1.setAdapter(adapterAnnounce);
lv1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Object selectedObj =adapterAnnounce.getItem(position).getId();// this will get you selected obj of itemAnnounce
String obj = (String)selectedObj.toString();
Intent i = new Intent(SuggestionMain.this, announce_Page.class);
i.putExtra("annId",obj);
startActivity(i);
}
});
});
} else {
Log.d("TAG", "No such document");
}
} else {
Log.d("TAG", "get failed with ", task.getException());
}
}
});
the error pops
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.districtapp, PID: 12764
java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.Date com.google.firebase.Timestamp.toDate()' on a null object reference
at com.example.districtapp.SuggestionMain$1.lambda$onComplete$0$SuggestionMain$1(SuggestionMain.java:65)
at com.example.districtapp.-$$Lambda$SuggestionMain$1$70rkZQjkWJS7wHwVoKS2O7TV5ls.onEvent(Unknown Source:4)
at com.google.firebase.firestore.Query.lambda$addSnapshotListenerInternal$2(Query.java:1133)
at com.google.firebase.firestore.Query$$Lambda$3.onEvent(Unknown Source:6)
at com.google.firebase.firestore.core.AsyncEventListener.lambda$onEvent$0(AsyncEventListener.java:42)
at com.google.firebase.firestore.core.AsyncEventListener$$Lambda$1.run(Unknown Source:6)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
I have impression about this sort of thing when I touch firestore the first time,So i tried to start the send activity first not the view,it works out but just for once,second time it shows the same bug,I tried to finish the whole activity listview when onclick to sendpage,still dont work,
Firestore is getting the data perfectly, and after restarting the app, listview shows the data, so the function is working though.
suggest field
You are getting NullPointerException because of the following line of code:
Date date = timestamp.toDate();
And this is because the timestamp object in:
Timestamp timestamp = (Timestamp) snapshot.getData().get("createdAt");
Has the value of null. To solve this, please change the above line of code to:
if (snapshot.getDate("createdAt") != null) {
Date timestamp = snapshot.getDate("createdAt");
//Do what you need to do with this timestamp
}
Besides that, a query like this:
firebaseFirestore.collection("Suggestion").whereEqualTo("recID",recID).orderBy("createdAt", Query.Direction.DESCENDING)
Requires an index. To add such an index please check my answer from the following post:
Firestore whereEqualTo, orderBy and limit(1) not working
I have the following code in my "AddFragment.java" file for adding data into firebase firestore, firebase storage and firebase database. Regarding firebase storage and firebase firestore working, the firebase database is not working, despite configured properly.
imageUpload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(filePath!=null) {
String LostPetName = petName.getText().toString().trim();
String userID = firebaseAuth.getCurrentUser().getUid();
String path = userID+"_"+filePath.hashCode()+".jpg";
StorageReference petPhotos = storageReference.child(path);
DocumentReference documentReference = firebaseFirestore.collection("Lost_Pets").document(path);
DatabaseReference myDatabase = firebaseDatabase.getReference("pets");
// -------------------------
// ADDING AN IMAGE START
petPhotos.putFile(filePath).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(getActivity(), "Imagine încărcată cu succes", Toast.LENGTH_SHORT).show();
// -------------------------
// ADDING A MAP LatLng START
String markerId = myDatabase.push().getKey();
AddMarker coord = new AddMarker(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude(), userID);
assert markerId != null;
myDatabase.child(markerId).setValue(coord);
// ADDING A MAP LatLng END
// -------------------------
petPhotos.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>()
{
#Override
public void onSuccess(Uri downloadUrl)
{
imgUri = downloadUrl.toString();
imgID = imgUri;
Map<String,Object> pet = new HashMap<>();
pet.put("LostPetName", LostPetName);
pet.put("img_id", imgID);
pet.put("markerLatitude", String.valueOf(lastKnownLocation.getLatitude()));
pet.put("markerLongitude", String.valueOf(lastKnownLocation.getLongitude()));
documentReference.set(pet);
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getActivity(), "Eșuare adăugare imagine", Toast.LENGTH_SHORT).show();
}
});
// ADDING AN IMAGE END
// -------------------------
}
else{
Toast.makeText(getActivity(),"Nu s-a ales o imagine pentru animalul pierdut", Toast.LENGTH_SHORT).show();
}
}
});
}
If I add a Log.d(TAG, String.valueOf(lastKnownLocation.getLatitude()) + String.valueOf(lastKnownLocation.getLongitude()) + userID) there after the setValue function I can see my data correctly in the log.
The AddMarker function is as follows.
public static class AddMarker {
public double lat;
public double lng;
public String senderUid;
public AddMarker(double lat, double lng, String senderUid) {
this.lat = lat;
this.lng = lng;
this.senderUid = senderUid;
}
}
I have my firebase configured correctly in my gradle file.
Account connected and implementation set:
implementation 'com.google.firebase:firebase-database:20.0.0'
and also the rules in Firebase:
{
"rules": {
".read": true,
".write": true
}
}
If somebody knows something I don't, please help me. I'd be grateful.
From the comment chain it sounds like you may have downloaded the google-services.json before the Realtime Database was created, which may lead to it using the wrong URL.
I recommend downloading an updated google-services.json, adding that to your Android app, and trying again. If that doesn't work, you can also specify the correct URL in the code with FirebaseDatabase.getInstance("rescue-a-soul-default-rtdb.europe-west1.firebasedatabase.app")....
Also see:
Firebase Database points to wrong database URL
I'm getting this error when i create new user on firebase from my sign-up form :
java.lang.NullPointerException: Can't pass null for argument 'pathString' in child()
I search about this error on google and on YouTube but i don't found something for my program.
Here is a part of my code on SignUpActivity.java:
final EditText email = findViewById(R.id.email_address);
final EditText display_name = findViewById(R.id.display_name);
final EditText password = findViewById(R.id.pass_sign_up);
final EditText comfirm_pass = findViewById(R.id.comfirm_pass);
final Button submit = findViewById(R.id.submit_btn_signup);
final TextView signin = findViewById(R.id.textView8);
final FirebaseAuth mAuth = FirebaseAuth.getInstance();
final String[] error = new String[1];
final ProgressBar loading_icon = findViewById(R.id.progressBar2);
// hide loading icon \\
loading_icon.setVisibility(View.GONE);
signin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(SignupActivity.this,MainActivity.class);
startActivity(intent);
}
});
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loading_icon.setVisibility(View.VISIBLE);
String email_input = email.getText().toString();
String display_name_input = display_name.getText().toString();
String password_input = password.getText().toString();
String comfirm_pass_input = comfirm_pass.getText().toString();
if (email_input.isEmpty() || display_name_input.isEmpty() || password_input.isEmpty() || comfirm_pass_input.isEmpty()){
error[0] = "Please fill all the values and try again";
Toast.makeText(SignupActivity.this, error[0], Toast.LENGTH_LONG).show();
loading_icon.setVisibility(View.GONE);
}else{
if (!password_input.equals(comfirm_pass_input)){
error[0] = "passwords do not match";
Toast.makeText(SignupActivity.this, error[0], Toast.LENGTH_LONG).show();
loading_icon.setVisibility(View.GONE);
}else{
mAuth.createUserWithEmailAndPassword(email_input,password_input).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull #NotNull Task<AuthResult> task) {
if (task.isSuccessful()){
finish();
// set display name for user \\
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
.setDisplayName(display_name_input).build();
user.updateProfile(profileUpdates);
DatabaseReference mRef = FirebaseDatabase.getInstance().getReference();
mRef.addValueEventListener(new ValueEventListener(){
#Override
public void onDataChange(#NotNull DataSnapshot dataSnapshot){
// Get the max_user_id to set the main user id and create the user on Firebase real-time DB \\
String maxUserId = dataSnapshot.child("max_user_id").getValue().toString();
int maxUserIdToInt = Integer.parseInt(maxUserId);
int userId = maxUserIdToInt+1;
newUserId = String.valueOf(userId);
mRef.child("users").child(newUserId).child("name").setValue(display_name_input);
}
#Override
public void onCancelled(#NotNull DatabaseError databaseError){
Toast.makeText(SignupActivity.this,"error: " + databaseError, Toast.LENGTH_LONG).show();
}
});
mRef.child("users").child(newUserId);
Intent intent = new Intent(SignupActivity.this,HomeActivity.class);
startActivity(intent);
}else{
loading_icon.setVisibility(View.GONE);
error[0] = "failed to sign up, the email address aleready exist or the password lenght is lower than 6 characters";
Toast.makeText(SignupActivity.this, error[0], Toast.LENGTH_LONG).show();
}
}
});
}
}
}
});
}
}
NOTE: i'm beginner on firebase for android applications. Also i created today my account here and stackoverflow is so cool and helpfull
When you call child(), you need to pass a non-null String as the parameter. In your case, newUserId is null for some reason. Hence you call child(newUserId), Firebase throws an exception.
The way forward should be check if the way you are accessing child with path max_user_id is correct or not. You can keep a breakpoint at that location and then go through the structure of dataSnapshot to get the correct path.
The problem is in the last line in this fragment:
DatabaseReference mRef = FirebaseDatabase.getInstance().getReference();
mRef.addValueEventListener(new ValueEventListener(){
#Override
public void onDataChange(#NotNull DataSnapshot dataSnapshot){
// Get the max_user_id to set the main user id and create the user on Firebase real-time DB \\
String maxUserId = dataSnapshot.child("max_user_id").getValue().toString();
int maxUserIdToInt = Integer.parseInt(maxUserId);
int userId = maxUserIdToInt+1;
newUserId = String.valueOf(userId);
mRef.child("users").child(newUserId).child("name").setValue(display_name_input);
}
#Override
public void onCancelled(#NotNull DatabaseError databaseError){
Toast.makeText(SignupActivity.this,"error: " + databaseError, Toast.LENGTH_LONG).show();
}
});
mRef.child("users").child(newUserId);
That line does nothing meaningful, but it executes before newUserId = String.valueOf(userId), which means you're passing in an initialized newUserId and that causes the error messages.
Since this line mRef.child("users").child(newUserId); does nothing anyway, you can safely remove it.
As a general rule: you should only use the newUserId inside the onDataChange or in code that is called from there. For this reason, I recommend making it a local variable in onDataChange instead of a field or otherwise broader scope. For more on why this is, see Is it possible to synchronously load data from Firebase? and Setting Singleton property value in Firebase Listener.
I'm using Firebase for login, but I want the user to also be added to the Real-Time Database so I can link the User with further data.
When a user registers, I can see that the user has been added to the authentication section of Firebase, and the user is able to log in but it does not get added to the Real-Time Database.
Here is my code
db = FirebaseDatabase.getInstance();
users = db.getReference("Users");
User user = new User();
user.setEmail((editEmail.getText().toString()));
user.setPassword((editPass.getText().toString()));
user.setName((editName.getText().toString()));
user.setPhone(editPhone.getText().toString());
users.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.setValue(user)
I also set an onSuccess/fail listener with Toasts letting me know if it failed or not. And neither of the toasts execute. I do have read/write enabled on my DB.
Define Variable.
private DatabaseReference userRef;
in OnCreate method.
userRef = FirebaseDatabase.getInstance().getReference().child("Users");
in a signup button
String getUserName = usernameEditText.getText.toString;
String getBio = bioEditText.getText.toString;
//and you should use the validates
if(getUserName.equals("")
{
usernameEditText.setError("Field Required");
}
else if(getBio.equals("")
{
bioEditText.setError("Field Required");
}
else
{
final HashMap<String , Object> profileMap = new HashMap<>();
profileMap.put("uid" , FirebaseAuth.getInstance().getCurrentUser().getUid());
profileMap.put("name" , getUserName);
profileMap.put("status" , getBio);
userRef.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.updateChildren(profileMap)
.addOnCompleteListener(new OnCompleteListener<Void>()
{
#Override
public void onComplete(#NonNull Task<Void> task)
{
if (task.isSuccessful())
{
Log.v("Profile Updated" , "Profile Updated Successfully");
Intent intent = new Intent(SettingsActivity.this , MainActivity.class);
startActivity(intent);
finish();
progressDialog.dismiss();
Toast.makeText(SettingsActivity.this, "Your profile Info has been updated", Toast.LENGTH_SHORT).show();
}
}
});
}
I am trying to retrieve profile data of the currently logged in user from Firebase Realtime Database. I have authenticated my users using email and password. I then saved the signup data on the database, as an object as follows: (All of this code is onCreate in SignUpActivity). I saved the data as User objects. My User model class has getters and setters, parameterized and blank constructors.
´´´´// Initialize FirebaseAuth and DatabaseReference
mFirebaseAuth = FirebaseAuth.getInstance();
mDatabaseRef = FirebaseDatabase.getInstance().getReference("users");
mFirebaseAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(SignUpActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
//save all data to database
String mUserId = mFirebaseAuth.getCurrentUser().getUid();
User user = new User(email, name,tel, address1,address2,user_type, mUserId);
//add to database
mDatabaseRef.child(mUserId).setValue(user);
//open main activity
Intent intent = new Intent(SignUpActivity.this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
Thus, mUserId is the userId of authenticated users. My database structure is as follows, and the rules are default public.
wish-store-42facaddclose
users
2GbVFSMFrihqVJ8OAXBa56owNW93
address1: "juja"
address2: "Town"
email: "a.bea#gmail.com"
phone: "+237638256239"
userId: "2GbVFSMFrihqVJ8OAXBa56owNW93"
userName: "Beatrice Njambi"
userType: "Buyer Account"
Now, to retrieve data in MainActivity, this is the code I’m using in onCreate:
//instantiate firebaseAuth
mFirebaseAuth = FirebaseAuth.getInstance();
Then onStart;
userName = (TextView) findViewById(R.id.userNameHeader);
//check to see if user is logged in
mFirebaseUser = mFirebaseAuth.getCurrentUser();
if (mFirebaseUser == null) {
//the user is not logged in, start login activity
loadLogInView();
} else {
String mUserId = mFirebaseUser.getUid();
root = FirebaseDatabase.getInstance().getReference();
DatabaseReference mDatabaseRef = root.child("users").child(mUserId);
ValueEventListener profileListener = new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
User user = dataSnapshot.getValue(User.class);
userName.setText(user.getUserName());
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.i("Read failed", databaseError.getMessage());
}
};
mDatabaseRef.addValueEventListener(profileListener);
}
I had tried to debug, and it says there is a null pointer exception for mUserId. So, the problem is correctly referencing the userId of the authenticated users. Please help, I really don’t understand what I’m doing wrong.
Thanks in advance.
Try to add the ValueEventListener for the database object directly, rather than setting it later. Try to check if you have initialized the FirebaseAuth.
mAuth = FirebaseAuth.getInstance();
mAuth.getCurrentUser();
FirebaseUser mUser = mAuth.getCurrentUser();
String uId = mUser.getUid();
String personName=mUser.getDisplayName();
String personEmail=mUser.getEmail();
String personPhoto=mUser.getPhotoUrl();
try this