I am building an app using Firebase. I would like to know which is the best way to set a current user session with Swift and Firebase. Should I make a User Object and assign the ID to that object as an attribute and then set it nil when the user logs out? Or is there a simpler way sharing that currentUserID across view controllers?
Firebase comes with solution to this:
let userID: String = FIRAuth.auth()!.currentUser!.uid
print(userID)
Just found out.
Related
I'm trying to make a login screen and made a database with Firebase by Google. The way I tried to make accounts in database is just by making a new child which is "Users" and then the next child would be a user (which is uniquely defined with a unique username). Then, user has other attributes and an attribute called loggedIn which is set to String 'false' but when on loginScreen login goes successfully set to String 'true'. How can I know after login and when that LoginViewController goes away which account has logged in exactly on that phone (simulator at the time) because there can be more users at one time with the attribute value 'loggedIn' set to 'true' and because of that can't go back to database to check that. I'm really new at this and don't know if this whole approach is okay by making in real-time database something like that and actually checking that by the attribute. Maybe I have to use some kind of a local database or something similar?
Swift 4, iOS development, Xcode 9
If you just want to persist locally the login status you may use UserDefaults. Just have a key called currentUser and set the value as his unique Id.
Once a user logs out just clear that key.
You can also use that to determine whether to launch the login screen when the app opens.
But it may be better to use something like AWS Cognito or similar services to handle user management.
Are you building an iOS app only or a cross-platform project?
I'm not sure this is the perfect answer for you. However, some of my apps use CloudKit and the login is authenticated and only then opens up areas of the app on the user's device. I'm sure if you wanted to check the status of successful logins, the authentication on the cloud could update as confirmation and you could subsequently access the cloud database using the CloudKit Dashboard.
It's quite intuitive and works seamlessly with Xcode.
I have a class called LoginManager, defined as an NSObject. Included in there is an optional String variable called accessToken with setter and getter functions for saving and retrieving my access token, including an option for clearing the token which would be used upon logout. There is also a function to check the status of the key.
var accessToken: String? {
get {
return //key from storage
}
set {
if newValue == nil {
//remove key from storage
} else {
//save key to storage
}
}
}
func isUserLogedIn() -> Bool {
return self.accessToken != nil
}
In my own case, I have an application manager object that changes the root view controller based on this info.
LoginManager.singleton.isUserLogedIn() ? loadMainView() : loadLoginView()
So the resulting view controller is never loaded unless the user is logged in. Is that useful to you?
In my app I have to validate user generated content, to do that I saw that with the panel of Firebase is not a fast thing, so I searched and I found Firebase FireAdmin, but it's not free and what I want is only change a value of approvation from not to yes (after have seeing content).
It's a good idea to make a viewcontroller hide for all exept from me by checking firauth property of Firebase?
let userID : String = (Auth.auth().currentUser?.uid)!
if userID == myid... { show view controller...
Thanx in advance
No it's not a good idea. This value can be changed or the controller can be access if your code is usafe. The application will be heavier for a controller that will not be used by users.
You have to build an admin interface if you don't want to pay for FirebaseAdmin.
In function of what you are looking for, you can also have a look at Firebase Database where you can read and edit values.
Background:
I have an app where new users complete a sign-up form (consisting of a username, email, and a password) to register for an account. When the new user submits the form, the app checks its Firebase Database to see if the username has already been taken. The problem here is that observeSingleEvent(of:with:) is not getting the newest data. When I update the data directly from the Firebase console, the changes are not reflected back in the returned results of observeSingleEvent(of:with:). Even between app restarts, the new data changes are not returned.
The only thing I've seen on the issue is here. A user says not to have persistence enabled when using observeSingleEvent(of:with:). But, I have persistence disabled. Also, I set the keepSynced() on the FIRDatabase instance to false (and I've tried true as well). No luck with either setting.
Here's an example of what I am trying:
let usersDatabaseReference = FIRDatabase.database().reference().child("users")
usersDatabaseReference.keepSynced(false)
// Query the database to see if the username is available
// The user with the username "mark" was removed from the database via the Firebase console
let username = "mark" // This user used to exist in the database (and was previously added through the app).
usersDatabaseReference.child(username).observeSingleEvent(of: .value, with: { (snapshot) in ... } )
The above code block should return the newest data (one where the user "mark" should not exist).
I am wondering if anyone else ran into this problem, or if anyone has possible solutions.
Note: Developing using iOS 10.1 and swift 3.
the observeSingleEvent(of:with:) return the value only one time
try this :
refHandle = postRef.observe(FIRDataEventType.value, with: { (snapshot) in
let postDict = snapshot.value as? [String : AnyObject] ?? [:]
// ...
})
this will add a listener on database event link
I recommend you refactor your JSON data model using the username as key. Doing this, you should get an error when trying to create a duplicate user in the database.
So, my problem had nothing to do with caching or fetching old results. Some of my code logic depended on checking the value of the snapshot parameter that was passed back in the completion handler for observeSingleEvent(of:with:). I wrongly assumed that I could check for a null database value by comparing it with nil; this led to a misinterpretation of results.
The best way to actually check for a null database fetch is by calling the exists() method on a FIRDataSnapshot instance. exists() returns true if the snapshot contains a non-null value.
I'm building an app using Firebase Database, Auth & Storage.
Basically, my users can sign up / sign in via Firebase Auth, then I store data for each of these users on Firebase Database.
I have been looking for the best way to get the Current User's data available throughout the app without having to re-fetch the information I need from Firebase on different screens.
Very few resources on Stack. Some people do talk about creating a CurrentUser singleton available globally, but others say that it's bad practice.
Now, maybe fetching the data as and when I need them might be the best practice solution, but I just felt it was strange to re-write the same piece of code again and again on each screens.
Any thoughts on this? I'd be really grateful if you guys have insights.
Isn't the logged in user data already available globally? I mean you can always access any logged in user related data by -
let userID = FIRAuth.auth()!.currentUser!.uid
The way uid available in this code snipped you can access any data related to user as long as the user is logged in. Do check if the current user is not nil before executing that, but i assume you will anyways take care of that.
You can make a struct with which you can access the values:-
struct userGlobalInfo{
var userID : String!
var userName : String!
var userEmail : String!
init(id : String!, name : String!, email : String!){
self.userID = id
self.userName = name
self.userEmail = email
}
}
I have created a PFObject called UserDataTable which stores information like username, password, Name, emailID, age, city, state, etc. of the user.
I am not sure how to authenticate the user to server using PFObject but can do so using PFUsers(). I know that PFUsers is a sub-class of PFObject so there must be a way to access those properties using my PFObject.
Can anyone help me out with the same. I am using SWIFT for coding.
let UserDataBase = PFObject(className: "UserDataBase")
UserDataBase["userId"] = "aamirdbx"
UserDataBase["userName"] = "Aamir Bilal"
UserDataBase["userPassword"] = "pass"
UserDataBase["userEmailId"] = "aamirdbx#gmail.com"
I would like to Sign In using information in this UserDataBase which is a PFObject.
I know how we can do the same using PFUser() but I want to avoid using a bunch of different Objects.
You should be using PFUser for this no matter what. PFUser already has all the built in authentication protocols, session tokens, security and ACL built in for you, which as someone who is just getting started is not something you want to try and manage yourself. You can add extra information to your Parse User class if you need to store additional information, or you can create another table, and have a pointer in your user class to the data in the other table, but for your sake and your user's sake, please don't try to handle this yourself.
After that chunk of code you should call userDataBase.saveInBackground() or saveInBackgroundWithBlock but then you would have to do a lot more coding every time they log in to authenticate and sync objects with the user etc. The included PFUser subclass does a lot of the heavy lifting for you, plus you can add properties to the user subclass so that would probably be a better option.