1

I have been struggling with this problem for a few days now and I am not making much progress, any help would be appreciated. I am new to FireStore but really like the possibilities it offers. I have successfully managed to get basic documents from Android and iOS apps using Plugin.CloudFirestore and Xamarin.Forms.

However I need some back-end services, things like data set-up etc and need to be able to connect to FireStore via regular old C# desktop app. So I followed the quick start guide, Nuget'ed Google.Cloud.Firestore, set the environment variable and no matter how I try the code I get "PERMISSION_DENIED: Missing or insufficient permissions."

Some details, I am using a service account set with Project Owner permissions and have not changed the default access rules yet. I know the environment variable is set-up correctly and the file is found. All packages are most recent. Frustrating that my iOS/Android apps are working, but this is not, I expected more issues with the mobile apps. As I am still exploring all this is just in a unit test so I can execute and change the code pretty quickly.

Help would be really appreciated before I start banging my head on the desk :-)

[TestClass]
public class UnitTest1
{
    [TestMethod]
    public void TestMethod1()
    {
        Task<string> task = Task.Run<string>(async () => await GetUserName());
        var x = task.Result;
        return ;

    }

    private async Task<string> GetUserName()
    {
        string projectId = "matchesJson";
        FirestoreDb db = FirestoreDb.Create(projectId);
        string retVal = "";

        try
        {
            CollectionReference col = db.Collection("users");
            // Exception thrown on next line
            QuerySnapshot snapshot = await col.GetSnapshotAsync();
            // get some data
            retVal = "";
        }
        catch (Exception e)
        {
            retVal =  e.Message;
        }
        return retVal;
    }

}

---- EDIT ADDING RULE ------- -- Today is March 3nd 2020 --

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // This rule allows anyone on the internet to view, edit, and delete
    // all data in your Firestore database. It is useful for getting
    // started, but it is configured to expire after 30 days because it
    // leaves your app open to attackers. At that time, all client
    // requests to your Firestore database will be denied.
    //
    // Make sure to write security rules for your app before that time, or else
    // your app will lose access to your Firestore database
    match /{document=**} {
      allow read, write: if request.time < timestamp.date(2020, 3, 28);
    }
  }
}
drHodge
  • 76
  • 8

2 Answers2

1

I found the issue. It is not very clear in the documentation, but when using a service account you need to add the permission to the account separately. This can be done in the google console by searching for the identity and applying the correct permission. For now I granted 'project owner' just for this POC, but there is probably a more granular permission.

Thanks for reading and thanks for the comments 'ralemos'.

drHodge
  • 76
  • 8
0

As you can check on this documentation, you can see that the default rules are to do not allow anyone read/write access and since you said that you did not change them, this is probably what is causing the issue.

You security rules should now be set to something similar to this:

match /databases/{database}/documents {
  match /{document=**} {
    allow read, write: if false;
  }
}

You have to change the allow part to the following to get access:

allow read, write: if true;

This will allow everyone to access it, if you want to segregate access you will have to figure out what are the conditions to give access according to your app's needs and the documentation mentioned previously should be of help by then too.

Let me know if this works.

Ralemos
  • 5,571
  • 2
  • 9
  • 18
  • The default rule has a bunch of comments around it, with a warning. // This rule allows anyone on the internet to view, edit, and delete // all data in your Firestore database. It is useful for getting. .etc. I will add the rule into the question as it wont fit here. Thanks for taking the time to look. – drHodge Mar 03 '20 at 15:52
  • Just to check if the problem is indeed in there, change it to `allow read, write: if true;` as I suggested, if it does work, indeed the condition is not being met, maybe because the value are not being properly compared or one of them is undefined, try changing the timestamps to miliseconds with `.toMillis()` so that the comparison can be made with numbers – Ralemos Mar 03 '20 at 16:14
  • Set to this, but it doesnt help. match /{document=**} { allow read, write: if true; } – drHodge Mar 04 '20 at 01:29
  • I am using a service account that I created within FireStore would this make a difference. Also kind of interesting that the iOS / Android versions work. – drHodge Mar 04 '20 at 01:30