Hi @jdgamble555 !
Thank you for your help! Funny enough, I think I was actually discussing Firebase limitations with you on the Fireship slack!
As of right now, I did a couple of things, but I could not get this working.
I added
# Dgraph.Authorization {"JWKUrl":"https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com", "Namespace": "https://dgraph.io/jwt/claims", "Audience": ["my-firebase-app-id"], "Header": "X-Auth-Token"}
to my schema.
I also installed the GraphQL flutter package and set it up. I can access the db and perform all requests just fine using the link consisting of my endpoint and the token. Does this mean the token concatenating process was successful?
static AuthLink authLink = AuthLink(
getToken: () => 'Bearer ${UserService.token}',
);
static Link link = authLink.concat(_httpLink);
As for the cloud functions, I set up this in my index.js and deployed it to Firebase.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.addUserClaim = functions.https.onCall((data, context) => {
return admin.auth().getUserByEmail(data.email).then(user=>{
return admin.auth().setCustomUserClaims(user.uid, {
"https://dgraph.io/jwt/claims":{
"USER": data.email
}
});
}).then(() => {
return {
message: `Success!`
}
}).catch(err => {
return err
})
})
I added the function call to my login method, so that whenever somebody logs in, a claim is added and the token I get, gets added to the client link. In the future, I feel like I should probably re-do this and call the cloud function from an onAuthStateChanged() function, but for testing, this seems fine.
So far so good, but as soon as I add rules to my schema, it seems like I never meet the requirements. I have a User schema, with an email. This is the same email that gets added to the claim I set up.
In my app, I call a function to query a user by their username. The goal is to only allow this if the email attached to that user is the same as the email of the currently logged in user (this is not a real usecase, just my testing example).
query MyQuery($eq: String = "") {
queryUser(filter: {username: {eq: $eq}}) {
username
}
}
My User schema looks like this:
type User
@auth(query: { rule: """
query($USER: String!) {
queryUser(filter: {email: {eq: $USER}}) {
email
}
}"""
})
{
id: ID!
firebaseId: String
email: String @search(by: [hash, fulltext])
username: String @search(by: [hash, fulltext])
following: [User] @hasInverse(field: "followers")
followers: [User]
profilePhotoUrl: String
accountCreated: DateTime
description: String
}
What am I missing here?
Some ideas:
- The rule is flawed
- $USER does not fetch the currently logged in user
- My query doesn’t add up with the rule
- The user claim is not added properly
Best,
Alex.