How to debug a Firebase authentication rule? - swift

Within Firebase, I've implemented a rule to restrict access to a node to the user that's currently logged on. The node looks like this:
{
"app": {
"my_team": {
"a_really_long_uid_string": {
"Lionel_Messi" = true,
"Christiano_Ronaldo" = true
}
}
}
}
and I've created the following rule (based on the online Firebase documentation), which should mean a logged in user can see only their own data (i.e. no other user's data).
{
"rules": {
"my_team": {
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid"
}
}
}
}
My client environment is in Swift and I've made a simple test routine,
func testAuthentication() {
print("test: \(uid)")
FirebaseRef.child("my_team").observe(.value, with: { (snapshot) in
let snapshot = snapshot.value as! [String: AnyObject]
print("test2: \(snapshot)")
}) { (error) in
print(error.localizedDescription)
}
}
When I run the code, I get the first print in the console ("test: a_really_long_uid_string") but don't get the second print statement.
If I change the rule to restrict access to any logged in users, I get both print statements in the XCode console.
{
"rules": {
"my_team": {
"$uid": {
".read": "auth != null",
".write": "auth != null"
}
}
}
}
Does anyone know what's up or how I can troubleshoot this? I'm wondering if either auth.uid or $uid are nil or something on the server, which could be a reason for access being denied.

Related

Firebase Realtime IOS can't read data permission denied

This is the error in the console
Unable to get latest value for query FQuerySpec (path: /Oeuvres/13, params: {
}), client offline with no active listeners and no matching disk cache entries
[Firebase/Database][I-RDB082010] Got data message: {
b = {
d = "Permission denied";
s = "permission_denied";
};
r = 3; }
When I run my code
var ref: DatabaseReference!
ref = Database.database().reference()
ref.child("Oeuvres").child(id).getData(completion: { error, snapshot in
guard error == nil else {
print("\(error!.localizedDescription)")
return;
}
print(snapshot.value)
});
Here's my rules on firebase realtime database
{
"rules": {
".read": true,
".write": "auth !== null"
}
}
Anyone can help me please ?

Firebase Authentication creates user but does not add their Info to database

I am new to using firebase and ios development in general. I am having an issue with adding user's info to the firestore database even though they are being added as authenticated users. Any Suggestions?
Auth.auth().createUser(withEmail: email, password: password) { (result, err) in
if err != nil {
self.errorLabel.text = "Error Creating User"
self.errorLabel.alpha = 1
} else {
let db = Firestore.firestore()
db.collection("users").addDocument(data: ["firstname":firstname, "lastname":lastname, "uid":result!.user.uid]) { (error) in
if error != nil {
self.errorLabel.text = "error saving user data"
self.errorLabel.alpha = 1
}
}
self.transitionScreens()
}
}
}
}
Change your code to the following:
// Add a new document with a generated ID
var ref: DocumentReference? = nil
ref = db.collection("users").addDocument(data: [
"firstname": firstname,
"lastname": lastname,
"uid": result!.user.uid
]) { err in
if let err = err {
print("Error adding document: \(err)")
} else {
print("Document added with ID: \(ref!.documentID)")
}
}
Using this print statement print("Error adding document: \(err)") you can know exactly what the error is.
Also change your security rules to the following:
// Allow read/write access to all users under any conditions
// Warning: **NEVER** use this rule set in production; it allows
// anyone to overwrite your entire database.
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if true;
}
}
}
Check out the following different rules you can give access to users depending on the data
service cloud.firestore {
match /databases/{database}/documents {
//allows all users to read and write, but dangerous as any one can flood your database
match /public_collection/{document=**} {
allow read, write: if true;
}
//only read access
match /public_read_collection/{document=**} {
allow read: if true;
allow write: if false;
}
//prefered for storing users personal info, users can access only their data
match /users/{userId} {
allow read, write: if request.auth.uid == userId;
}
//any authenticated user can access or write data
match /posts/{documentId} {
allow read, write: if request.auth.uid != null;
}
}
}

Cannot read property of 'uid' of null

I need help, I used firebase as back-end and Ionic 4 as front-end.
I have error on console where when I first open/lunch the app, I received Cannot read property of 'uid' of null on console.
I read some related solutions but I haven't found one that solves my problem.
Below is the code when I implemented it in my app:
initializeApp() {
this.afAuth.auth.onAuthStateChanged(user => {
const userId = user.uid;
this.db.doc(`accounts/${userId}`).valueChanges().pipe(
take(1)
).subscribe(userData => {
const role = userData['role'];
if (role == 'USER') {
console.log('we got a customer user');
this.router.navigateByUrl('/tabs/home')
} else if (role == 'VENDOR') {
console.log('we got a seller user');
this.router.navigateByUrl('/vendor-tabs/home-vendor')
}
})
})
}
An auth state change listener is called when a user is either signed in and signed out. user will be null if not signed in. This means you have to check if user is truthy before you start accessing properties on it.
this.afAuth.auth.onAuthStateChanged(user => {
if (user) {
// user is signed in
const userId = user.uid;
}
else {
// user is signed out - can't use properties of user.
}
}
See the API documentation.
This is what I did to get rid of the cannot read property of 'uid' null.
this.afAuth.auth.onAuthStateChanged(user => {
if (user) {
const userId = user.uid;
this.db.doc(`accounts/${userId}`).valueChanges().pipe(
take(1)
).subscribe(userData => {
const role = userData['role'];
if (role == 'USER') {
console.log('we got a customer user');
this.router.navigateByUrl('/tabs/home')
} else if (role == 'VENDOR') {
console.log('we got a seller user');
this.router.navigateByUrl('/vendor-tabs/home-vendor')
}
})
} else {
return of(null);
}
})

Firebase Geofire permission denied

I'm using Firebase Geofire to get user locations to store them in my database. I get an error when I try to run a query:
Listener at /RDio5CZF2fcJTUOcaeNJhuvYP2Q2 failed: permission_denied
2017-09-19 22:34:24.809 HeartQuest[26419] <Warning> [Firebase/Database][I-RDB038012] Listener at /RDio5CZF2fcJTUOcaeNJhuvYP2Q2 failed: permission_denied
An error occurred getting the location for "firebase-hq": Optional("Permission Denied")
The errors occur after running the following query:
let userID = User.current?.key
let geofireRef = Database.database().reference()
let geoFire = GeoFire(firebaseRef: geofireRef)
geoFire?.getLocationForKey(userID!, withCallback: { (location, error) in
if (error != nil) {
print("An error occurred getting the location for \"firebase-hq\": \(error?.localizedDescription)")
} else if (location != nil) {
print("Location for \"firebase-hq\" is [\(location?.coordinate.latitude), \(location?.coordinate.longitude)]")
} else {
print("GeoFire does not contain a location for \"firebase-hq\"")
}
})
}
Can anyone please explain what the location key is and why I might not have permission for it? I'm using CLLocationManager to request the user's permission for their phone's location.
EDIT: Firebase rules
{
"rules": {
".validate": "auth != null",
".write": "auth != null",
"users" : {
".read": "auth != null",
".indexOn" : ["email","username"],
"$userId": {
".write": "data.val() == null || (newData.val() == null && $userId === auth.uid)"
}
}
}
}

FB.Api error on unity

I got error to get facebook name on Unity 3D, this function clearly working 2 weeks ago,
FB.Init(this.InitCallback, this.OnHideUnity);
private void InitCallback ()
{
if (FB.IsInitialized) {
if (FB.IsLoggedIn) {
FB.LogInWithReadPermissions(new List<string>() { "public_profile","email" }, this.AuthCallback);
} else {
}
} else {
Debug.Log("Failed to Initialize the Facebook SDK");
}
}
private void AuthCallback (ILoginResult result) {
if (FB.IsLoggedIn) {
FB.API("/me?fields=name", HttpMethod.GET, this.LoginCallback2);
} else {
//Debug.Log("User cancelled login");
}
}
void LoginCallback2(IResult result)
{
if (result.Error != null) {
Debug.Log(result.Error);
}
else{
fbid = result.ResultDictionary ["id"].ToString();
}
}
I got error on LoginCallback2 function, debug as follow:
UnityEngine.Debug:Log(Object)
connect:LoginCallback2(IResult) (at Assets/connect.cs:983)
Facebook.Unity.<Start>d__9:MoveNext()
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
The short answer is that either FB hasn't been initialized, or the user is NOT logged in. Below I have shared my own code for retrieving the User's full name and their FBID. You will want to check to make sure that the following is true before calling this code section:
FB.IsInitialized == true
and
FB.IsLoggedIn == true
if (result != null) {
if (string.IsNullOrEmpty(result.Error)) {
if (result.ResultDictionary != null)
if (result.ResultDictionary.ContainsKey("name")) {
result.ResultDictionary.TryGetValue("name", out Name);
}
if (result.ResultDictionary != null)
if (result.ResultDictionary.ContainsKey("id")) {
result.ResultDictionary.TryGetValue("id", out FBID);
}
}
}