I am trying to add user details to Firestore db, but can't write data in it.
Actually none of the listeners are triggered neither onSuccess() nor onFailure().
here is my code.
Map<String,Object> userlol = new HashMap<>();
userlol.put("name",name);
userlol.put("email",email);
userlol.put("uid",currentUser.getUid());
Log.d(TAG, "we are here");
CollectionReference dc = db.collection("users");
DocumentReference dd = dc.document(currentUser.getUid());
dd.set(userlol)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Toast.makeText(SignupActivity.this, "User Added" ,
Toast.LENGTH_SHORT).show();
Log.d(TAG,"User added to database");
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(SignupActivity.this, "ERROR" +e.toString(),
Toast.LENGTH_SHORT).show();
Log.d(TAG, e.toString());
}
});
There is no toast nor the Log in my logcat.I can see
D/logging: we are here
This log and logs after this method.
There is no issue with rules as onFailure() is also not working.
I have searched every possible thing but nothing worked.
The only way I can get neither of the callbacks to trigger is when there is no network connection on my device. In that case the behavior makes sense, since the task is only considered completed when the data has been committed (or rejected) on the server.
To easily see if the Firestore client indeed can't connect to the server, enable debug logging:
FirebaseFirestore.setLoggingEnabled(true);
I see log entries like this after doing so:
11-12 07:56:21.366 10034-10066/com.firebase.firestorestackoverflow I/Firestore: (0.6.6-dev) [zzetk]: (b6322ac) Stream closed with status: zzcd{code=UNAVAILABLE, description=null, cause=java.net.UnknownHostException: Unable to resolve host "firestore.googleapis.com": No address associated with hostname
at java.net.InetAddress.lookupHostByName(InetAddress.java:470)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
at java.net.InetAddress.getAllByName(InetAddress.java:215)
at io.grpc.internal.zzbj$zzb.zztu(Unknown Source)
at io.grpc.internal.zzbk.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: android.system.GaiException: android_getaddrinfo failed: EAI_NODATA (No address associated with hostname)
at libcore.io.Posix.android_getaddrinfo(Native Method)
at libcore.io.ForwardingOs.android_getaddrinfo(ForwardingOs.java:55)
at java.net.InetAddress.lookupHostByName(InetAddress.java:451)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:252)
at java.net.InetAddress.getAllByName(InetAddress.java:215)
at io.grpc.internal.zzbj$zzb.zztu(Unknown Source)
at io.grpc.internal.zzbk.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
}.
well for anyone having that problem in the future just Uninstall your application and reinstall it, as savage as it seams it works(y)
I had the same problem.
First of all turning on the logs helped a lot as #Frank van Puffelen suggested.
In my case I got "The Cloud Firestore API is not available for Datastore Mode projects".
So I went to GCP and created manually a collection by changing the db to a native one. And then I had an option on the gui.
Now the error changed to "FirebaseFirestoreException: permission_denied: missing or insufficient permissions"
So I changed the permissions under the "rules" tab in firestore.
And that fixed it for me :)
I guess the problem was the permissions from the beginning, but I can't tell for sure now.
I had the same error. In my case, I was creating a user and automatically logging him/her out, for them to log manually.
I removed the sign out, as data appears not to be written if there is no user logged in.
Do you have a user signed in when the data is written? Creating a user signs him/her in automatically.
Hope it helps!
It appears that just like after adding new permissions in the manifest file, the app has to be reinstalled to register the changes. I tried reinstalling the app after adding the firestore connection and everything worked fine. voila!
Related
I'm building an app where I store app data in the app-specific-folder on Google Drive. I've been able to setup everything related to file storage and retrieval. The problem I'm facing is regarding permissions. The user has an option to disconnect the app from the Google Drive settings panel.
I use the DriveScopes.DRIVE_APPDATA meaning https://www.googleapis.com/auth/drive.appdata scope to save data.
I'm trying to figure out how to find out if this has happened on the app side. If I try to continue using the drive related apis, with the app being disconnected, then it crashes with a UserRecoverableAuthException.
com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException
at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:297)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:868)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:476)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:409)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:526)
at abhiank.maplocs.ui.drivesync.DriveSyncService.onHandleIntent(DriveSyncService.kt:68)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:78)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.os.HandlerThread.run(HandlerThread.java:67)
Caused by: com.google.android.gms.auth.UserRecoverableAuthException: NeedPermission
at com.google.android.gms.auth.zze.zzb(Unknown Source:13)
at com.google.android.gms.auth.zzd.zza(Unknown Source:77)
at com.google.android.gms.auth.zzd.zzb(Unknown Source:20)
at com.google.android.gms.auth.zzd.getToken(Unknown Source:7)
at com.google.android.gms.auth.zzd.getToken(Unknown Source:5)
at com.google.android.gms.auth.zzd.getToken(Unknown Source:2)
at com.google.android.gms.auth.GoogleAuthUtil.getToken(Unknown Source:55)
at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential.getToken(GoogleAccountCredential.java:267)
at com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential$RequestHandler.intercept(GoogleAccountCredential.java:292)
I tried the following to figure out if the app does not have the permissions or scopes.
Look at data inside GoogleSignInAccount instance received from GoogleSignIn.getLastSignedInAccount(this). This had the following scopes available in account.grantedScopes() after app had been disconnected. drive.appdata is shown even though app is disconnected.
[https://www.googleapis.com/auth/drive.appdata, https://www.googleapis.com/auth/userinfo.profile, https://www.googleapis.com/auth/userinfo.email, openid, profile, email]
Last thing I tried was hasPermissions method available in GoogleSignIn. I checked if the APP_DATA scope was available with this call and it returned true. So no help there either.
GoogleSignIn.hasPermissions(account, Scope(DriveScopes.DRIVE_APPDATA))
I'm really stuck now. Any help will be really appreciated. Thanks.
I ended up using a try-catch around my drive related code and catching the UserRecoverableAuthIOException. According to the documentation, this is called when -
UserRecoverableAuthExceptions signal Google authentication errors that
can be recovered with user action, such as a user login.
This has worked decently well for me. Considering the fact that this question has not received any other answers in 2 years, there doesn't seem to be any method to fetch the information about whether the app is disconnected or not via an API or SDK call.
Here's the code I use
fun getGoogleDriveService(context: Context): Drive {
val credential = GoogleAccountCredential.usingOAuth2(context, setOf(DriveScopes.DRIVE_APPDATA))
credential.selectedAccount = GoogleSignIn.getLastSignedInAccount(context)!!.account
return Drive.Builder(NetHttpTransport(), GsonFactory(), credential)
.setApplicationName(DriveSyncService.APP_NAME)
.build()
}
try {
val driveService = getGoogleDriveService(this)
var fileList = driveService.files().list().execute()
//...
//more code
} catch (e: UserRecoverableAuthIOException) {
/*
Doing a sign-out on the googleSignInClient so that there is no mismatch
in sign-in state and so that when I start sign-in process again, it
starts afresh
*/
googleSignInClient.signOut()
/*
Then I show a pop up telling user that app was disconnected and
to sign in again. And then on click I start the sign-in flow again.
*/
} catch (e: GoogleJsonResponseException) {
//https://googleapis.dev/java/google-api-client/latest/index.html?com/google/api/client/googleapis/json/GoogleJsonResponseException.html
//404 is file being updated/deleted was not found
if (e.message != null && e.message!!.contains("storageQuotaExceeded")) {
//todo handle storage exceeded error. Inform user
}
} catch (e: IOException) {
//todo handle network error
}
I have been working to solve this problem for like one & a half day and couldn't find any solution to it.
Working on below Android Lollipop and others.
Tried mostly all the solution.
Even FailureListener is not triggered.
Code:
DatabaseReference mFirebaseRef = FirebaseDatabase.getInstance().getReferenceFromUrl(constants.FIREBASE_URL+"rootssahaj/authGplus/users/teachers");
ProfileInformation pro= new ProfileInformation(email,personName,personPhotoUrll,personGooglePlusProfile,personPhotoUrllThumb,"true");
Log.e("SahajLOGwq", "CalledInside" +prefs.getBoolean("callProfileToFireBase",true)+" Email: "+EmailPref +pro+" yo > "+pro.getUserNAME());
mFirebaseRef.child(EmailPref).child("profile").setValue(pro, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if (databaseError != null) {
Log.e("SahajLOGwq", "Data could not be saved. " + databaseError.getMessage());
} else {
Log.e("SahajLOGwq", "Data saved successfully.");
}
}
});
Logcat:
08-07 01:18:32.866 30547-30547/com.rana.sahaj.myyu E/SahajLOGwq: NOTICE__android USER SIGNED IN
08-07 01:18:32.921 30547-30547/com.rana.sahaj.myyu E/SahajLOGwq: CalledOutsidetrue
08-07 01:18:32.922 30547-30547/com.rana.sahaj.myyu E/SahajLOGwq: CalledInsidetrue Email: narveshrana68 com.rana.sahaj.myyu.profile.ProfileInformation#e6ddcfd yo > Narvesh Rana
*Rules for now
{
"rules": {
".read": true,
".write": true
}
}
*Edit:
this is what I found after Debug LogLevel of Firebase
08-07 18:22:08.275 8863-9013/com.rana.sahaj.myyu D/RepoOperation: set: /testforwrite
08-07 18:22:08.275 8863-9013/com.rana.sahaj.myyu D/DataOperation: set: /testforwrite true
08-07 18:22:08.289 8863-9013/com.rana.sahaj.myyu D/RepoOperation: Aborting transactions for path: /testforwrite. Affected: /testforwrite
08-07 18:22:08.290 8863-9013/com.rana.sahaj.myyu D/RepoOperation: set: /rootssahaj/authGplus/users/teachers/narveshrana68/profile
08-07 18:22:08.291 8863-9013/com.rana.sahaj.myyu D/DataOperation: set: /rootssahaj/authGplus/users/teachers/narveshrana68/profile {
isTeacher=true
picurl=https://l400
picurl50DP=https://lh230
userEmail=na.om
userNAME=Narvesh Rana
}
08-07 18:22:08.296 8863-9013/com.rana.sahaj.myyu D/RepoOperation: Aborting transactions for path: /rootssahaj/
I am able to reproduce this and get the same D/RepoOperation: Aborting transactions for path: /testforwrite. Affected: /testforwrite on Lollipop when I am connected to wifi, disable the actual internet connectivity, and then re-enable internet connection (all with the device remaining connected to wifi network). After this, if I try to perform a setValue() write, about 18 minutes will pass before Firebase reconnects and the setValue() completes. I reached out to the Firebase team and was told this is expected behavior due to the Android OS basically neglecting to informing apps when the connection is restored.
The only way to resolve in my experience is either disabling and re-enabling WiFi, or restarting the app (restarting the activity won't help).
Firebase support got back to me and suggested calling goOffline() followed by goOnline() - I verified this immediately reconnects the Firebase database. What I do now is set a Handler with my own timeout for setValue(), since I can't seem to depend on DatabaseError being thrown with onComplete().
I need help with Firebase read Rules.
this is the structure of my database
db:{
user:{
uid0:{
name:"mario",
lastname:"super"
}
uid1:{
name:"bubu",
lastname:"gogo"
}
uid1:{
name:"fajio",
lastname:"mkokd"
}
}
}
my rules:
{
"rules": {
"user":{
"$uid":{
".read":"auth.uid === $uid",
}
}
}
}
With rules simulator there are not problem to read user's info.
In my activity im using recycler view for populate list with user's name but
i get Permission Denied.
WHat's te problem?? What's wrong??
this is my query for populate list
Query query = FirebaseDatabase.getInstance().getReference().child("user");
EDIT:
`10-28 17:28:22.680 8317-8387/com.scidaconnectpeople.www.scida W/SyncTree: Listen at /user failed: DatabaseError: Permission denied
10-28 17:28:22.680 8317-8317/com.scidaconnectpeople.www.scida W/FirebaseRecyclerAdapter: com.google.firebase.database.DatabaseException: Firebase Database error: Permission denied
at com.google.firebase.database.DatabaseError.toException(Unknown Source)
at com.firebase.ui.database.FirebaseRecyclerAdapter.onCancelled(FirebaseRecyclerAda pter.java:199)
at com.firebase.ui.database.FirebaseRecyclerAdapter$1.onCancelled(FirebaseRecyclerAdapter.java:116)
at com.firebase.ui.database.FirebaseArray.notifyCancelledListeners(FirebaseArray.java:119)
at com.firebase.ui.database.FirebaseArray.onCancelled(FirebaseArray.java:99)
at com.google.android.gms.internal.zzaip.zza(Unknown Source)
at com.google.android.gms.internal.zzakn.zzcxi(Unknown Source)
at com.google.android.gms.internal.zzaks$1.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5538)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:958)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:753)`
Firebase Database security rules are enforced on the level where you try to attach the query. Since you attach a query on /users, that's where it checks if you have read permission. Since you don't have read permission on /users, the query is rejected/cancelled.
This is often unexpected to developers new to Firebase. We call it "rules are not filters", both in the documentation and here on Stack Overflow.
There are lot of chances that problem you are facing due to google-services.json.
please confirm that you have downloaded updated json file.
Check these Docs
I need help about an issue that I am looking for hours and still not solved.
I am trying to use the linking current user with facebook property of parse server using android. I am also using the singin with facebook property, but have no problems there. However, when I use the linking property with the code below, the facebook enter username password dialog opens. Then I give permission to read the listed data from facebook and click ok. When it turns back to my app, nothing happens and I see the lines below in the log.
As the emulator I use Nexus 6 API 23 Android 6.0 x86
My code is:
System.out.println("I am here 1");
List<String> permissions = Arrays.asList("public_profile", "email", "user_friends");
System.out.println("I am here 2");
if (!ParseFacebookUtils.isLinked(ParseUser.getCurrentUser())) {
System.out.println("I am here 3");
ParseFacebookUtils.linkWithReadPermissionsInBackground(ParseUser.getCurrentUser(), this, permissions, new SaveCallback() {
#Override
public void done(ParseException ex) {
System.out.println("I am here 4");
if (ParseFacebookUtils.isLinked(ParseUser.getCurrentUser())) {
Log.d("MyApp", "Woohoo, user logged in with Facebook!");
}
else {
Log.e("MyLast", "unexpected error of mine", ex);
}
}
});
}
In the log I see:
06-16 10:57:40.049 11878-11878/com.my_last.mylast W/BindingManager: Cannot call determinedVisibility() - never saw a connection for the pid: 11878
06-16 10:57:40.084 11878-11987/com.my_last.mylast E/Surface: getSlotFromBufferLocked: unknown buffer: 0x9cbad8b0
06-16 10:57:40.305 11878-11987/com.my_last.mylast E/Surface: getSlotFromBufferLocked: unknown buffer: 0xb40982e0
In the println lines, I see until "I am here 3". before the log lines above.
Any help would be great, I looked everywhere but could not found any reasons. I use the code inside a fragment, and I also tried using getActivity() rather than this, but same result.
Situation
I've implemented push notification with Parse in ANDROID. Everything works great (I can receive push/send etc.), the only thing is that when I install my application it happens this:
if it is the first install ever on the device: no problem
if it is not the first install (this means that the device has already made a PARSE/GCM registration) it generates this error:
Error generated
02-12 11:12:28.054 15564-15579/com.hoxell.hoxellbrowser E/ParseCommandCache﹕ Failed to run command.
com.parse.ParseException: at least one ID field (installationId,deviceToken) must be specified in this operation
at com.parse.ParseCommand.onPostExecute(ParseCommand.java:404)
at com.parse.ParseRequest$5.then(ParseRequest.java:342)
at com.parse.ParseRequest$5.then(ParseRequest.java:339)
at bolts.Task$10.run(Task.java:486)
at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:97)
at bolts.Task.completeAfterTask(Task.java:482)
at bolts.Task.continueWithTask(Task.java:358)
at bolts.Task.continueWithTask(Task.java:369)
at bolts.Task$8.then(Task.java:415)
at bolts.Task$8.then(Task.java:407)
at bolts.Task$10.run(Task.java:486)
at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:97)
at bolts.Task.completeAfterTask(Task.java:482)
at bolts.Task.access$200(Task.java:27)
at bolts.Task$6.then(Task.java:351)
at bolts.Task$6.then(Task.java:348)
at bolts.Task.runContinuations(Task.java:515)
at bolts.Task.access$600(Task.java:27)
at bolts.Task$TaskCompletionSource.trySetResult(Task.java:570)
at bolts.Task$TaskCompletionSource.setResult(Task.java:604)
at bolts.Task$10$1.then(Task.java:498)
at bolts.Task$10$1.then(Task.java:490)
at bolts.Task$9.run(Task.java:453)
at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:97)
at bolts.Task.completeImmediately(Task.java:449)
at bolts.Task.access$100(Task.java:27)
at bolts.Task$5.then(Task.java:316)
at bolts.Task$5.then(Task.java:313)
at bolts.Task.runContinuations(Task.java:515)
at bolts.Task.access$600(Task.java:27)
at bolts.Task$TaskCompletionSource.trySetResult(Task.java:570)
at bolts.Task$TaskCompletionSource.setResult(Task.java:604)
at bolts.Task$10$1.then(Task.java:498)
at bolts.Task$10$1.then(Task.java:490)
at bolts.Task$9.run(Task.java:453)
at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:97)
at bolts.Task.completeImmediately(Task.java:449)
at bolts.Task.access$100(Task.java:27)
at bolts.Task$5.then(Task.java:316)
at bolts.Task$5.then(Task.java:313)
at bolts.Task.runContinuations(Task.java:515)
at bolts.Task.access$600(Task.java:27)
at bolts.Task$TaskCompletionSource.trySetResult(Task.java:570)
at bolts.Task$TaskCompletionSource.setResult(Task.java:604)
at bolts.Task$10$1.then(Task.java:498)
at bolts.Task$10$1.then(Task.java:490)
at bolts.Task$9.run(Task.java:453)
at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:97)
at bolts.Task.completeImmediately(Task.java:449)
at bolts.Task.continueWith(Task.java:323)
at bolts.Task.continueWith(Task.java:334)
at bolts.Task$10.run(Task.java:490)
at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:97)
at bolts.Task.completeAfterTask(Task.java:482)
at bolts.Task.access$200(Task.java:27)
at bolts.Task$6.then(Task.java:351)
at bolts.Task$6.then(Task.java:348)
at bolts.Task.runContinuations(Task.java:515)
at bolts.Task.access$600(Task.java:27)
at bolts.Task$TaskCompletionSource.trySetResult(Task.java:570)
at bolts.Task$TaskCompletionSource.setResult(Task.java:604)
at bolts.Task$10$1.then(Task.java:498)
at bolts.Task$10$1.then(Task.java:490)
at bolts.Task$9.run(Task.java:453)
at bolts.BoltsExecutors$ImmediateExecutor.execute(BoltsExecutors.java:97)
at bolts.Task.completeImmediately(Task.java:449)
at bolts.Task.continueWith(Task.java:323)
at bolts.Task.continueWith(Task.java:334)
at bolts.Task$10.run(Task.java:490)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:864)
Yeah, it generates it but the app do not crash! and the app still works: push notifications too, but you can understand that this is not 100% reliable.
E/ParseCommandCache﹕ Failed to run command.
com.parse.ParseException: at least one ID field (installationId,deviceToken) must be specified in this operation
What does he want..? What should I do? What is the cause of the problem? Here is my code:
Application.java
#Override
public void onCreate() {
super.onCreate();
// Initialize the Parse SDK.
Parse.initialize(this, "x", "x");
// Specify an Activity to handle all pushes by default.
PushService.setDefaultPushCallback(this, MainActivity.class);
ParseInstallation.getCurrentInstallation().saveInBackground();
}
In my mainActivity I just concatenate the deviceToken (in my case it is the installationId) into my userAgent: and this work fine too! Even if the error is generated, the installationID is inserted into the userAgent.
MainActivity.java
deviceToken = ParseInstallation.getCurrentInstallation().getInstallationId();
webSettings.setUserAgentString(userAgent + " ||" + deviceToken);
Am I making any mistakes into my code?
Thank you
Try the following below:
ParseInstallation.getCurrentInstallation().saveInBackground(new SaveCallback()
{
#Override
public void done(ParseException e)
{
PushService.setDefaultPushCallback(Application.this, MainActivit.class);
}
});
As I recall, you do not need to save the installation when using setDefaultPushCallback. Try removing the saving of installation and see if it still happens.
setDefaultPushCallback will automatically save the installation for you. Cannot remember where I found it, but at some forum it was told to be the behavior. I guess a second save right after (without the first yet completed) brings the installation in a bad state, causing the non-fatal error msg.