I´m trying to connect two Apps to same database project with firebase, I can create a new user into new application to the same database but when I try to retrieve data valueeventlistener always return null after few seconds, I check already google-services.json and two files are different, packages and ids, is there someone with same problem?
Query query = myRef.child("xxxx/").orderByChild("xxxx").equalTo(Utils.decodeEmail(userEmail));
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String stLogoUrl;
stLogoUrl = dataSnapshot.child("imageEncode").getValue(String.class);
try {
if (stLogoUrl!=null) {
bitmapPhotoProfile[0] = decodeFromFirebaseBase64(stLogoUrl);
} else {
}
imgLogo.setImageBitmap(bitmapPhotoProfile[0]);
} catch (Exception e){
e.printStackTrace();
}
}
Related
I wanted to add new sub-Collection to a existing document. Should i create new POJO class to add Sub-Collection or any other way to do it. I wanted to add new Sub-Collection to existing document ID.I am new to android and Firestore. Thanks in advance.this is my Database
i tried this method but stuck couldn't succed
private void setNewCategory(String downloadUrl){
FirebaseFirestore db = FirebaseFirestore.getInstance();
DocumentReference newMainCatRef = db
.collection("HomeFeed")
.document("5HEkE0ac7sMa7Gjnvf3E")
.collection("MainCategory")
.document();
itemId = newMainCatRef.getId();
MainCategory category = new MainCategory();
category.setCategory_id(itemId);
category.setCategory_name(category_name.getText().toString());
category.setCategory_url(downloadUrl);
category.setPriority(priority.getValue());
newMainCatRef.set(category).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "onSuccess: Success on Updating the new Field to cat");
FirebaseFirestore NC = FirebaseFirestore.getInstance();
CollectionReference NewCategory = NC
.collection("Categories")
.document("tUdFCajDcQT995jX6G4k")
.collection(category_name.getText().toString());
NewCategory.add()
category_name.setText("");
priority.setValue(0);
category_image.setImageResource(R.drawable.ic_android);
category_progress.setVisibility(View.INVISIBLE);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(mContext, "Failed to add New Catgory Try again!", Toast.LENGTH_SHORT).show();
}
});
}
There is no need to make something special. As I see in your code, you're already using the right reference:
CollectionReference NewCategory = NC
.collection("Categories")
.document("tUdFCajDcQT995jX6G4k")
.collection(category_name.getText().toString());
category_name.getText().toString() being the name of the sub-collection but the problem rises in the following line of code:
NewCategory.add()
Where you aren't passing anything as an argument. You should pass a custom object or a Map in order to be able to write something in the database.
I am trying to move firestore user records after authentication using batch. It seems to copy the records but not deleting.
Android app begins in anonymous mode, when user decides to signup, i try to move his records to the new SMS authenticated user.
Before signup, i get all user records using listRef.get() and a Success listener. I than save the resulted QuerySnapshot. After SMS authentication success, i use the snapshot to copy and delete.
I use the snapshot.getReference() to find the record. I confirmed in debug mode the reference path is correct
To make sure the delete code working, i made a test method and it worked.
The path in firestore is: lists/users/uid/
private void retrieveDataBeforeVerify() {
CollectionReference listRef = db.collection( "lists" ).document("users").
collection( mCurrentUser.getUid() );
listRef.get()
.addOnSuccessListener( new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
mQuerySnapshot = queryDocumentSnapshots; //Save snapshort
startPhoneNumberVerification(mPhoneNumberField.getText().toString()); //Start auth
}
} );
}
}
After the SMS authentications
private void moveDataToNewUser() {
if (mQuerySnapshot != null) {
if (mCurrentUser != null) {
DocumentReference listRef = db.collection( "lists" ).document( "users" );
WriteBatch batch = db.batch();
for (QueryDocumentSnapshot documentSnapshot : mQuerySnapshot) {
Main main = documentSnapshot.toObject( Main.class );
batch.set( listRef.collection( mCurrentUser.getUid() ).document( ) , main); //Copy working correctly
DocumentReference reference = documentSnapshot.getReference(); //On debug, reference shows correct path
batch.delete( reference ); //Delete does not work
}
batch.commit().addOnFailureListener( new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e( TAG, "moveDataToNewUser: batch failed" );
}
} ).addOnSuccessListener( new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.d( TAG, "moveDataToNewUser: batch success" );
}
} );
}
}
}
update
I changed the reference to something non existing and still the onSuccess listener fires. How can it be??
DocumentReference reference = documentSnapshot.getReference().collection( "22" ).document("123");
update
if i comment the first two lines on the for-loop then delete is success. It looks as if the batch cannot process both set and delete on the same batch. I also tried using a transaction but got similar results. does this makes sense?
btw - i am using com.google.firebase:firebase-firestore:18.2.0, i believe it is the latest
for (QueryDocumentSnapshot documentSnapshot : mQuerySnapshot) {
//Main main = documentSnapshot.toObject( Main.class );
//batch.set( listRef.collection( mCurrentUser.getUid() ).document( ) , main); //Copy working correctly
DocumentReference reference = documentSnapshot.getReference(); //On debug, reference shows correct path
batch.delete( reference ); //Delete success!
}
Im working on a android app with email-password login.
The user is created in a local sqlite db and in firebase + auth.
Situation: The user uninstalls the app, the local db is deleted. Then the user re-installs the app and wants to login using old credentials, But the user does not exist locally thus the app tries to create a new. - but the user already exist remote in my firebase users table + auth.
Question: How do I query either firebase auth or firebase for the user info only using email, pass and perhaps a few extras.
Most answers I found refer to using the update event from firebase, but at this point it´s not possible as the user is not yet authenticated
I solved it myself.
It was simple and not at all. A part of my fix is below. But in short. I get the user from firebase, then make an update to firebase and then I restore the user in a addValueEventListener(new ValueEventListener()
_fbAuth.signInWithEmailAndPassword(_email, _password).addOnCompleteListener(LoginActivity.this, new OnCompleteListener<AuthResult>() {
#Override
public void onComplete(#NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Log.d(TAG, "Firebase login success");
FirebaseUser fbUser = _fbAuth.getCurrentUser();
String uid = fbUser.getUid();
FireBaseWriteHelper wh = new FireBaseWriteHelper();
FireBaseReadHelper fireBaseReadHelper = new FireBaseReadHelper(getApplicationContext(), uid, Util.VERSION_KEY_FREE);
DateFormat format = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault());
Date date = new Date();
wh.UpdateUserLastLogIn(uid, format.format(date));
_user = _userHelper.CheckUserExist(_email, _password);
mPasswordView.setError(null);
mEmailView.setError(null);
} else {
try {
throw task.getException();
} catch (FirebaseAuthInvalidUserException e) {
} catch (FirebaseAuthInvalidCredentialsException e) {
} catch (FirebaseNetworkException e) {
} catch (Exception e) {
}
}
}
});
You can use the Firebase in Offline mode. You don't need to use two databases. Guide here.
I'am using Firebase Storage to get a list of images on Android, but every time when the App is started this list is downloaded, I want store persistence on Android the images and download only if is necessary. So I need to check if the images that will downloaded already are on the smartphone. I'am using the FirebaseDatabase to store the name of the files, for the Database I can check the persistence. I think need store images on the storage of device, but I don't know to check before download, so the best way is set persistence FirebaseStorage if possible.
My code looks like this:
FirebaseDatabase:
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference databaseReference = database.getReference().child("nomes_imagens");
final Map<String,Object> mapNomesImagens = new HashMap<>();
databaseReference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.i(TAG,"onDataChanged()");
Iterator<DataSnapshot> iterator = dataSnapshot.getChildren().iterator();
while( iterator.hasNext() ) {
DataSnapshot snapshot = iterator.next();
mapNomesImagens.put(snapshot.getKey(),snapshot.getValue());
n1++;
}
makeList(mapNomesImagens);
Log.i(TAG,"Mapa: " + mapNomesImagens.toString());
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.i(TAG,"onCancelled");
}
});
FirebaseStorage:
public boolean makeList(Map<String,Object> map) {
final FirebaseStorage storage = FirebaseStorage.getInstance();
try {
Set<String> set = map.keySet();
for(final String nomeExercicio : set) {
String nomeArquivo = String.valueOf(map.get(nomeExercicio));
final File localFile = File.createTempFile("ImagensExercicios","bmp");
storage.getReference().child("ImagensExercicios").child(nomeArquivo).getFile(localFile).
addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
Log.i(TAG,"onSuccess()");
Bitmap bitmap;
bitmap = BitmapFactory.decodeFile(localFile.getAbsolutePath());
Exercicio exercicio = new Exercicio(nomeExercicio,bitmap);
exercicios.add(exercicio);
n++;
}
}).
addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.i(TAG,"onFailure() " + e.getMessage());
}
}).
addOnCompleteListener(new OnCompleteListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onComplete(#NonNull Task<FileDownloadTask.TaskSnapshot> task) {
Log.i(TAG,"onComplete()");
}
}
});
}
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
AFAIK setpersistence enabling is intended for offline data storage. So it will refresh when the internet is available.
You can use Glide library to handle caching. Official firebase usage with Glide given below must be sufficient.
Link: https://github.com/firebase/FirebaseUI-Android/tree/master/storage
To load an image from a StorageReference, simply use the
FirebaseImageLoader class:
// Reference to an image file in Cloud Storage
StorageReference storageReference = ...;
// ImageView in your Activity
ImageView imageView = ...;
// Load the image using Glide
Glide.with(this /* context */)
.using(new FirebaseImageLoader())
.load(storageReference)
.into(imageView);
Send the picture path or URI in the phone, create a room android database, or if you are good with persistence that's ok. Use regular expression or regex to help tally the URI path from firebase to that of the phone path.
If both URI match then the file exists no need to download but if the URI does not match then the file does not exist then a download process is trigger
Remember regular expression or regex
Database Structure:
appname/users/userID/personal/Name
The child "name" is upadated in the database but is returning as null.
mChildReference = FirebaseDatabase.getInstance().getReference().child("users").child(uid).child("personal"); //DatabaseReference
ValueEventListener postListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Get Post object and use the values to update the UI
User post = dataSnapshot.getValue(User.class);
Toast.makeText(MainActivity.this, "Name: "+post.uname+"dob: "+post.udob+"phno: "+post.phone_number+"email: "+post.uemail, Toast.LENGTH_LONG).show();
Log.e("RETRIEVED DATA", "Name: "+post.getUname()+"dob: "+post.getDob()+"phno: "+post.getPhone_number()+"email: "+post.getEmail());
Log.e("DEBUG",dataSnapshot.getKey());
fname.setText(post.getUname());
}
#Override
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
Log.e("DEBUG", "loadPost:onCancelled", databaseError.toException());
// [START_EXCLUDE]
Toast.makeText(MainActivity.this, "Failed to load post.",
Toast.LENGTH_SHORT).show();
// [END_EXCLUDE]
}
};
mChildReference.addValueEventListener(postListener);
mPostListener = postListener;
If the database is acting wierd, make sure you double-check your database rules. You can try to make them public for now. I find this useful when I am developing.
In the Firebase Console, click Database -> RULES
Set all permissions to public (Warning anyone
can read and write!)
// These rules give anyone, even people who are not users of your app,
// read and write access to your database
{
"rules": {
".read": true,
".write": true
}
}
Try the query on Android again and see if it works.