Creating and using anonymous ID for user at the same time as creating an Auth uid Firebase?

202 Views Asked by At

I would like to know how to create a second (Anonymous) identifier for a user when they are creating an account.

The reason for this is I am letting a user create an account so they can be rewarded but I will need to know if they should be rewarded before logging in to their account again.

There is an account section of the app in a view controller which a user accesses all account related data. There is also another section of the app in the same view controller where any user has access to the info stored in that database, lets call it the 'Public database' which they can view without creating an account. (The user who creates an account can not view the public database unless they log out of their account)

The user needs to call to the Firebase Realtime Database without being logged in and then log in to their account later on that day to see if they've been rewarded for searching the correct branch in that public database.

For instance:

Lets say a user creates their account by using their email and a password. They start with 0 points and log out. They return to get an answer from the database before logging in again with their account later on or the next day and want to see if they have been rewarded for viewing that one branch of the database when they were not logged in. If they have viewed that branch, then when they do log in they will now have 1 point.

Any user will have access to those branches of the database but will not be rewarded if they don't create an account first. Users currently already do have access to those branches of the database but can not be identified because they don't need to be.

I am allowing a user to create an account to be rewarded for accessing the section of the database which any user already has access to.

I hope that makes sense.

I don't need to know how to create an account for a user, just how to identify the user when they are not logged in so when they do log in that they can write to their account without already knowing from their previous visit to the database that they accessed the section of the database that they weren't logged in for.

I know you want me to show some code whether relevant to the answer I'm looking for or not....

func createNewUser()
{
   guard let email = registerEmailField.text, let password = registerPasswordField.text, let name = registerNameField.text
        else
    {
        return
    }

   if self.registerEmailField.text!.isValidEmail == true
    {
        Auth.auth().createUser(withEmail: email, password: password)
        {
            authResult, error in
            if error != nil
            {
                self.newUserError()
                return
            }
            else
            {
            guard let uid = authResult?.user.uid
            else
            {
                return
            }
            let user = ["Name": name,
                        "email": email,
                        "password": password]
              
            let gold = self.goldLabel.text ?? "\(0)"
            let rewards = self.rewardLabel.text ?? "\(0)"

            let savingUserScores = ["gold": gold as Any,
                                    "rewards": rewards as Any]

        Database.database().reference().child("Users").child(uid).updateChildValues(user, withCompletionBlock:
        {
            (error, ref) in
            if let error = error
            {
                print("Failed to update database values with error: ", error.localizedDescription)
                return
            }
        Database.database().reference().child("Users").child(uid).child("scores").updateChildValues(savingUserScores, withCompletionBlock:
        {
            (error, ref) in
            if let error = error
            {
                print("Failed to update database values with error: ", error.localizedDescription)
                return
            }
            else
            {
                self.sendEmailVerification()
                self.hideRegisterWindow()
                self.hideLoginKeyboard()
            DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2), execute:
                    {
                        self.userView.isHidden = true
                        self.checkEmailButton.isHidden = false
                    })
            }
          })
        })
       }
     }
   }
  }
}


func logInUser()
{
  guard let email = logInEmailField.text, let password = logInPasswordField.text
    else
    {
        return
    }
    Auth.auth().signIn(withEmail: email, password: password)
    {
        [weak self] user, error in
        if error != nil
        {
           print("I can't put all this code in here")
        }
        else
        {
          guard let user = Auth.auth().currentUser
                else
            {
                return
            }
            if user.isEmailVerified
            {
              print("I can't put all of the code in here either")
            }
        }
    }
}


func displayUserScoresFromFirebase()
{
    guard let userID = Auth.auth().currentUser?.uid
    else
    {
        return
    }
    Database.database().reference().child("Users").child(userID).child("Name").observe(.value)
    {
        (snapshot)
        in
        guard let name = snapshot.value as? String else
        {
            return
        }
        self.accountNameLabel.text = "HI\n" + "\(name)"
    }
    Database.database().reference().child("Users").child(userID).child("scores").child("gold").observe(.value)
    {
        (snapshot)
        in
        guard let gold = snapshot.value
        else
        {
            return
        }
        let Gold = "\(gold)"
        self.goldLabel.text = Gold//"GOLD TOKENS\n\n" + Gold
    }
    Database.database().reference().child("Users").child(userID).child("scores").child("rewards").observe(.value)
    {
        (snapshot)
        in
        guard let rewards = snapshot.value
        else
        {
            return
        }
        let Rewards = "\(rewards)"
        self.rewardLabel.text = Rewards//"REWARD POINTS\n\n" + Rewards
    }
}


func loadPublicInfoFromDatabase()
{ 
    let ref = Database.database().reference(withPath: "*publicUserInfo")
    
    ref.child("publicInfo").child("publicInfo1").observe(.value)
    {
        (snapshot)
        in
        guard let publicInfo1 = snapshot.value
            else
        {
            return
        }
            self.publicInfoLabel.text = "\(publicInfo1)"
            
        ref.child("publicInfo").child("publicInfo2").observe(.value)
        {
            (snapshot)
            in
            guard let publicInfo2 = snapshot.value
                else
            {
                return
            }
                self.publicInfoLabel.text = "\(publicInfo2)"
        }
    }
}

A little more to complicate things, The main reason for all of this is that I need to only reward the user (Who has an account) if they view publicInfo2 but not publicInfo1.

Please excuse the way my code is structured✌️

1

There are 1 best solutions below

0
On

To handle this, the Guest account that they are using will need to be upgraded by linking it to a verified auth provider by completing the following steps:

  1. When the user signs up, complete the sign-in flow for the user's authentication provider up to, but not including, calling one of the FIRAuth.signInWith methods. For example, get the user's Google ID token, Facebook access token, or email address and password.
  2. Get an FIRAuthCredential for the new authentication provider
let credential = EmailAuthProvider.credential(withEmail: email, password: password)
  1. Pass the FIRAuthCredential object to the sign-in user's linkWithCredential:completion: method:
   user.link(with: credential) { (authResult, error) in
  // ...
}

Source: iOS Auth Convert Guest