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

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;
}
}
}

Related

how to connect postgres to azure ? (golang-azure)

I have an application that has only the POST method, and every time I make a request in that application, it saves some data for me in my postgres database..
locally my application works properly, but when I deploy and try to test it through the azure function app it returns a 500 error and says that it was not possible to store my information in the database..
here are some code snippets
go code:
func (h handler) sendgridWeb(c *gin.Context) {
data, _ := io.ReadAll(c.Request.Body)
var ListaEventoEmail []Email
if err := json.Unmarshal(data, &ListaEventoEmail); err != nil {
log.Fatal("Error when unrealizing content contained in Body")
}
for _, email := range ListaEventoEmail {
email.SgMessageId = email.SgMessageId[:strings.IndexByte(email.SgMessageId, '.')]
//-- PROCESSED --//
if email.Event == "processed" {
inserting := `insert into email (email_destinatario, enviado, id_sendgrid) values ($1, $2, $3)`
_, err := h.DB.Exec(inserting, email.Email, true, email.SgMessageId)
if err != nil {
log.Fatal("Error inserting data into email table")
}
}
//-- DELIVERED --//
if email.Event == "delivered" {
_, err := h.DB.Exec(`UPDATE email SET recebido=true WHERE id_sendgrid=$1`, email.SgMessageId)
if err != nil {
log.Fatal("Error when uploading email with DELIVERED event")
}
//-- OPEN --//
} else if email.Event == "open" {
_, err := h.DB.Exec(`UPDATE email SET recebido=true, aberto=true WHERE id_sendgrid=$1`, email.SgMessageId)
if err != nil {
log.Fatal("Error when uploading email with OPEN event")
}
} else if email.Event == "click" {
_, err := h.DB.Exec(`UPDATE email SET click = click + 1 WHERE id_sendgrid=$1`, email.SgMessageId)
if err != nil {
log.Fatal("Error when uploading email with CLICK event")
}
}
my connection string is stored in a toml file..
connection string:
# filename: config.toml
[postgres]
host = "132.168.0.22"
port = 5432
user = "postgres"
password = "ivaneteJC"
dbname = "webhook"
you can see that, in the HOST field I put my IP (fictitious ip)..
in my logic, when deploying to azure, my connection string should point to my machine, so I used the ip, thus performing the necessary operations on my database, but this does not happen .. when making a POST request by the postman (using the endpoint that o was provided when deploying to the azure function app, I get a 500 error and in my logs I get the message "Error inserting data into the email table" which is an error described in my go app, I believe I made a mistake somewhere that has a connection to the database, can someone help me?
function.json:
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
host.json:
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
}
}
},
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[3.*, 4.0.0)"
},
"customHandler": {
"description": {
"defaultExecutablePath": "main.exe",
"workingDirectory": "",
"arguments": []
},
"enableForwardingHttpRequest": true
}
}
local.settings.json:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "",
"FUNCTIONS_WORKER_RUNTIME": "custom"
}
}
I did as mentioned in a comment, I treated the error in an original way .. and the following error appeared:
"connectex: An attempt was made to access a socket in a way prohibited by its access permissions."
db:
type handler struct {
DB *sql.DB
}
type PostgreConfig struct {
Host string
Port int
User string
Password string
Dbname string
}
type MyConfig struct {
Postgres *PostgreConfig
}
func Init() *sql.DB {
doc, err := os.ReadFile("config.toml")
if err != nil {
panic(err)
}
var cfg MyConfig
err = toml.Unmarshal(doc, &cfg)
if err != nil {
panic(err)
}
stringConn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", cfg.Postgres.Host, cfg.Postgres.Port, cfg.Postgres.User, cfg.Postgres.Password, cfg.Postgres.Dbname)
db, err := sql.Open("postgres", stringConn)
if err != nil {
log.Fatal("Erro ao realizar conexão")
} else {
fmt.Println("Conectado")
}
fmt.Println(stringConn)
db.Ping()
return db
}
func OpenDB(DB *sql.DB) handler {
return handler{DB}
}

Allow access to customer data if user is part of privileged collection

The database structure is like so:
suppliers(collection)>user_email(document)
customers(collection)>user_email(document)>foo(field)
And the current firestore.rules is like so:
match /databases/{database}/documents {
//Base rule - fully restrictive
match /{document=**} {
allow read, write: if false;
}
//Checks if user is registered in the suppliers section
function isSupplierTeam(request) {
return exists(/suppliers/$(request.auth.token.email));
}
// Supplier self-data access
match /suppliers/{email} {
allow read, write: if request.auth.token.email == email;
}
match /suppliers/{email}/{document=**} {
allow read, write: if request.auth.token.email == email;
}
// Checking the Customer Sub-Section
match /customers/{email} {
allow read, write: if request.auth.token.email == email || isSupplierTeam(request);
}
match /customers/{email}/{document=**} {
allow read, write: if request.auth.token.email == email || isSupplierTeam(request);
}
}
And the query run in javascript, when logged in as a "supplier" is:
db.collection("customers").get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
console.log(doc.id);
console.log(doc.data());
});
})
.catch((error) => {
console.log("Error getting documents: ", error);
});
It doesn't seem to work and instead triggers a missing/insufficient permission error. How should I tweak my firestore.rules to allow suppliers to access the customer data?
So this works:
//Checks if user is registered in the suppliers section
function isSupplierTeam(request) {
return exists(/databases/$(database)/documents/suppliers/$(request.auth.token.email));
}
It seems like the full "URL" is needed to access the relevant firestore document.

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 ?

Firestore Rules: Only show documents if document field is false

I have a NSFW system where it checks the document if it is NSFW and if it is it updates the document field isNSFW to true. That works just fine but now I wanted to not show those documents to all users via settings a rule instead of querying it out.
This is what I have but it's not working...
javascript
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth.uid != null;
}
}
match /users/{user} {
allow read: if true;
}
match /docs/{doc} { // THIS HERE
allow read: if resource.data.isNSFW == false;
}
}
I tried adding request. before the resource and it still didn't work.
UPDATE:
javascript
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// match /{document=**} {
// allow read, write: if request.auth.uid != null;
// }
match /users/{user} {
allow read: if currentUser().uid != null;
}
match /docs {
allow read: if existingData().users[currentUser().uid] == false;
}
match /docs/{doc} {
allow write: if currentUser().uid != null;
}
}
// MARK - Funcs ---------------
function existingData() {
return resource.data
}
function incomingData() {
return request.resource.data
}
function currentUser() {
return request.auth
}
function isSignedIn() {
return request.auth != null;
}
}
Getting error:
Listen for Query(docs where users.`40S88coPQObEWSeiYMZIJlIKJkI2` == false order by __name__) failed: Status{code=PERMISSION_DENIED, description=Missing or insufficient permissions., cause=null}
If you are using Firebase Datastore, you can simply query 1
your data:
var myDB = db.collection("YOUR-DB-COLLECTION");
var query = myDB.where("isNSFW", "==", false);
If you are using GCP datastore, you do it this other way 2:
const query = datastore
.createQuery('YOUR-COLLECTION')
.filter('isNSFW', '=', false);
Your matches are not nested correctly. They should be inside the block that starts with match /databases/{database}/documents. Also, you should strongly consider removing the match on /{document=**} because that will let everyone read any document in the database if they're logged in, ignoring all other rules.

How to debug a Firebase authentication rule?

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.