Reputation: 532
In my Firestore, I want a Donors collection. Here are my security rules for it:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /Donors/{donor} {
allow read: if true;
allow create: if request.auth != null;
allow update, delete: if request.auth != null && request.auth.uid == resource.data.userId;
}
}
}
As can be seen from the rules, I want anybody to read any of the documents in the collection, I only want authenticated users to be able to create documents, and I want only the creators of the document to be able to change the document (see my Donor class below).
public class Donor {
private String Email;
private String Name;
private String City;
private String Country;
private String ImageURL;
private int Balance;
private String userId;
public Donor(String email, String name, String city, String country, String userId) {
this.Email = email;
this.Name = name;
this.City = city;
this.Country = country;
this.Balance = 0;
this.userId = userId;
}
}
I use the following code to create the document.
if (firebaseAuth.getCurrentUser() != null) {
Log.d("cs50", firebaseAuth.getCurrentUser().getEmail() + " signed in");
} else {
Log.d("cs50","signed out");
}
if (radioDonor.isChecked()) {
database.collection("Donor").document(email).set(new Donor(email,
getIntent().getStringExtra("name"),
getIntent().getStringExtra("city"),
getIntent().getStringExtra("country"),
firebaseAuth.getCurrentUser().getUid()))
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.e("cs50", "Error creating donor", e);
}
});
}
I get a message in my logcat "[email] signed in", which means that the user is authenticated using Firebase authentication. But the document is not created with the following error message:
2020-09-20 18:24:47.298 15566-15566/com.example.treeapp D/cs50: [email protected] signed in
2020-09-20 18:24:48.651 15566-15566/com.example.treeapp E/cs50: Error creating donor
com.google.firebase.firestore.FirebaseFirestoreException: PERMISSION_DENIED: Missing or insufficient permissions.
at com.google.firebase.firestore.util.Util.exceptionFromStatus(Util.java:117)
at com.google.firebase.firestore.core.SyncEngine.notifyUser(SyncEngine.java:521)
at com.google.firebase.firestore.core.SyncEngine.handleRejectedWrite(SyncEngine.java:451)
at com.google.firebase.firestore.core.MemoryComponentProvider$RemoteStoreCallback.handleRejectedWrite(MemoryComponentProvider.java:109)
at com.google.firebase.firestore.remote.RemoteStore.handleWriteError(RemoteStore.java:714)
at com.google.firebase.firestore.remote.RemoteStore.handleWriteStreamClose(RemoteStore.java:670)
at com.google.firebase.firestore.remote.RemoteStore.access$600(RemoteStore.java:53)
at com.google.firebase.firestore.remote.RemoteStore$2.onClose(RemoteStore.java:206)
at com.google.firebase.firestore.remote.AbstractStream.close(AbstractStream.java:344)
at com.google.firebase.firestore.remote.AbstractStream.handleServerClose(AbstractStream.java:398)
at com.google.firebase.firestore.remote.AbstractStream$StreamObserver.lambda$onClose$3(AbstractStream.java:151)
at com.google.firebase.firestore.remote.AbstractStream$StreamObserver$$Lambda$4.run(Unknown Source:4)
at com.google.firebase.firestore.remote.AbstractStream$CloseGuardedRunner.run(AbstractStream.java:67)
at com.google.firebase.firestore.remote.AbstractStream$StreamObserver.onClose(AbstractStream.java:137)
at com.google.firebase.firestore.remote.FirestoreChannel$1.onClose(FirestoreChannel.java:135)
at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:426)
at io.grpc.internal.ClientCallImpl.access$500(ClientCallImpl.java:66)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.close(ClientCallImpl.java:689)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.access$900(ClientCallImpl.java:577)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInternal(ClientCallImpl.java:751)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:740)
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:457)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at com.google.firebase.firestore.util.AsyncQueue$SynchronizedShutdownAwareExecutor$DelayedStartFactory.run(AsyncQueue.java:229)
at java.lang.Thread.run(Thread.java:764)
Caused by: io.grpc.StatusException: PERMISSION_DENIED: Missing or insufficient permissions.
at io.grpc.Status.asException(Status.java:541)
at com.google.firebase.firestore.util.Util.exceptionFromStatus(Util.java:115)
at com.google.firebase.firestore.core.SyncEngine.notifyUser(SyncEngine.java:521)
at com.google.firebase.firestore.core.SyncEngine.handleRejectedWrite(SyncEngine.java:451)
at com.google.firebase.firestore.core.MemoryComponentProvider$RemoteStoreCallback.handleRejectedWrite(MemoryComponentProvider.java:109)
at com.google.firebase.firestore.remote.RemoteStore.handleWriteError(RemoteStore.java:714)
at com.google.firebase.firestore.remote.RemoteStore.handleWriteStreamClose(RemoteStore.java:670)
at com.google.firebase.firestore.remote.RemoteStore.access$600(RemoteStore.java:53)
at com.google.firebase.firestore.remote.RemoteStore$2.onClose(RemoteStore.java:206)
at com.google.firebase.firestore.remote.AbstractStream.close(AbstractStream.java:344)
at com.google.firebase.firestore.remote.AbstractStream.handleServerClose(AbstractStream.java:398)
at com.google.firebase.firestore.remote.AbstractStream$StreamObserver.lambda$onClose$3(AbstractStream.java:151)
at com.google.firebase.firestore.remote.AbstractStream$StreamObserver$$Lambda$4.run(Unknown Source:4)
at com.google.firebase.firestore.remote.AbstractStream$CloseGuardedRunner.run(AbstractStream.java:67)
at com.google.firebase.firestore.remote.AbstractStream$StreamObserver.onClose(AbstractStream.java:137)
at com.google.firebase.firestore.remote.FirestoreChannel$1.onClose(FirestoreChannel.java:135)
at io.grpc.internal.ClientCallImpl.closeObserver(ClientCallImpl.java:426)
at io.grpc.internal.ClientCallImpl.access$500(ClientCallImpl.java:66)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.close(ClientCallImpl.java:689)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl.access$900(ClientCallImpl.java:577)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInternal(ClientCallImpl.java:751)
at io.grpc.internal.ClientCallImpl$ClientStreamListenerImpl$1StreamClosed.runInContext(ClientCallImpl.java:740)
at io.grpc.internal.ContextRunnable.run(ContextRunnable.java:37)
at io.grpc.internal.SerializingExecutor.run(SerializingExecutor.java:123)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:457)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at com.google.firebase.firestore.util.AsyncQueue$SynchronizedShutdownAwareExecutor$DelayedStartFactory.run(AsyncQueue.java:229)
at java.lang.Thread.run(Thread.java:764)
When I allow anyone to read and write using the following rules, the document gets created without any problem.
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}
I can't figure out exactly what I'm doing wrong. I am confirming that the user is authenticated in my code, but the Firestore database does not recognize the user as authenticated.
Please help me out.
Upvotes: 0
Views: 271
Reputation: 4670
Posting as Community Wiki, as in the comments was confirmed that the issue was solved.
The issue was with the different collection names used on the security rules and in the class code. In the security rules the name was Donors
, while in the class it was Donor
. Once this mistype in the names was fixed, the issue was fixed from the creation of documents.
Upvotes: 1