I'm working on an android app and I want to allow users to register using Facebook, Gmail etc.
My question is not how to do that, because there are many posts regarding that including tutorials written by Facebook and Google themselves.
I want to achieve something similar to the Stackoverflow log in - the users are allowed to login using Gmail for instance, while the site (or app) also keeps its own data about each user (namely, my profile).
I'm not quite sure how to achieve something like that in Android, since the Facebook and Google SDK's allow my app to access the user's facebook name, email (and any public information), but I don't think they allow me to add more data about this user my app needs for its own purposes.
What I was thinking of doing is to manage a DB of my own where I could store the additional data (for instance, using Parse.com), and use a common field to all services as a key (was thinking about email, since Facebook, Gmail & twitter all use that - do you recommend this?)
Are there other (better) ways to achieve what I want? perhaps Google offers something I don't know?
How safe is this (though I should mention that for now the app shouldn't gather any personal information).
As always, any help would be appreciated.
Thank you.
Store the user's email in your own database along with its session key (don't forget to update it after each login). When the user makes a request to the server after he logs in check the email and session key he provides and use them to get his row in the database, where you can store more information about them.
Regarding Parse.com: They have their own implementation of Facebook login.
Related
I wanted to know if when there's an firebase authentification, it's possible to get the source of this authentification?
To know if it's from my iphone app, android app or web app.
Why :
My web app isn't on the web, but on local server. I want to distribute this web app with server (It's for a personnal project but it could have 10 prototypes). So everybody can get my firebase config. And I don't want that someone can create account from the web firebase api because I accept google/apple and email/password auth. I can't disable email/password for my project purpose.
I hope this is clear.
To be more clear, if the email/password auth is created, is it possible to know if it's from android app or iphone app or webapp?
Thanks
The provided APIs for Firebase Auth don't give any indication which platform was used to create the account. Firebase intends for all accounts to work across all platforms using the provided SDKs and APIs accessible for each platform.
If you want to record your own per-user data in a database, you're free to do that. Note that this is not really "secure" in that each user could effectively manipulate your database or APIs to indicate whatever they want about their platform. If you do not have this sort of security in mind, then you can simply trust your own code to write, and late read, the user's platform in a database after they sign up.
To be more clear if the email/password auth is created, is it possible to know if it's from the Android app or iPhone app, or web app?
Yes, it's possible. Let's say we want to know if a user has signed in from Android. When the user creates an account from an Android device, most likely you are storing user data as objects in the database. The simplest solution I can think of is to add another property in your User class, called "platform" and set it to "Android". If the user signs up with an iPhone, then set the property to "iOS". Same thing for the web. Knowing that the user might change the device, every time the user opens the app check that value against the OS the user is using. If the OS is changed, also change the value accordingly. This way you'll always know the OS the user is using. If you allow the users to use multiple platforms, for Android, there is a function called getProviderData():
Returns a List of UserInfo objects that represents the linked identities of the user using different authentication providers that may be linked to their account.
Similar functions can be found for the other platforms as well.
I want to create a chat app for Android but instead of registering with an email or phone number I would like users to sign in with their account on an already existing website account. For example, If I'm creating a chat app specifically for movies, I would make the authentication through their IMDB account. Is there any way to do this? Usually I work with firebase.
You can do this but using firebase is meaningless in this scenario. Firebase is a "BaaS" (back-end as a service) which you generally use to store data or send notifications. In your example, you want to connect your users with their IMDB account so you already know the back-end you should use. To connect the users with a system you should read their API docs and send POST/GET requests which generally contains a username, a password, and an API key. After that depending on the service, you should get the JSON/XML response from the server, and let the user continue if the response code is 200.(SUCCESS). To make the call take a look at
https://developer.android.com/reference/java/net/HttpURLConnection
To test this with an API, take a look at themoviedb which is free to use.
https://www.themoviedb.org/documentation/api
Your question is fairly broad which makes it difficult to answer in any detail.
In any case, you want to authenticate your users so you know who-is-who. This means your users need to provide some form of credentials. You don't want users to create a new account, instead they should be able to use one of their existing accounts (e.g. IMDb) to authenticate themselves.
How to authenticate?
As Sam says, to allow a user to sign in with IMDb you need to be able to talk to IMDb's servers first. This means you need some form of API, that allows you to send HTTP requests to IMDb's servers.
As far as I can see, IMDb doesn't offer much in terms of a public API or any way to authenticate a user with their IMDb account.
You may want to look into Firebase Authentication instead. It already supports a number of services (Google, Facebook, Twitter, GitHub) and takes care of all the low level details. You want to build a chat app, not an identity service after all.
Do I still need my own database and user accounts?
Yes
Once a user is authenticated you may want to store some data about them (name, email, ...). The service used to authenticate a user may or may not provide you with this information. Users also may not want to share all of those details with your app. On top of that you probably want to be able to link a user's chat history with their account. This means you need to store this information somewhere.
What else?
All of this just takes care of authentication. You still need to provide the necessary infrastructure for users to actually be able to talk to one another. This means you need your own server that the app can use to route messages to other users. You could probably use some other Firebase services for this (e.g. Cloud Functions).
I am developing an Android application using Google's Firebase for the backend. I have been running through some tutorials, and they make the user sign in with their Gmail before using the app in order to read and write from the database (correct me if I'm wrong). I don't want this to be the case for the purpose of privacy and not allowing users to read and write data, so how would I not make the users authenticate with their Gmail, and instead for all reads and writes, use a general gmail specific to the app?
If I don't manually add each gmail account to the firebase console directly as either an editor or owner, then users cannot log into the app. I have been following Google's firebase tutorials found here: https://firebase.google.com/docs/auth/android/google-signin
Thanks
What you're describing sounds like Firebase anonymous authentication. Users can use an anonymous account to read and write as if they are fully authenticated, without having to go through any login process. Then, if you want, you can later give them the option to link that account to a fully identified authenticated account from an authentication provider, such as Google.
Note that anonymous accounts don't survive application uninstall, and they can't be used by the same person across different devices. If you want the user to be able to log in and out and retain use of the data your store on their behalf, you need to use an authentication provider to verify that the person is who they say they are.
How can you uniquely identify a user who has installed your app so that:
You will know it is them if they delete and reinstall your app;
You will know it is them if they install your app on a second device they intend to use simultaneously?
Just as an example, I see that the Netflix app will automatically link to your desktop account without any user interaction. I'm guessing that they use accountManager.getAccounts() or similar method, because they also require the GET_ACCOUNTS permission. But of course that permission is marked as Protection level: dangerous. Is there any technique to do this that is less invasive or potentially alarming?
The key to answering this is to be both simple (for the user) and minimally invasive. Android provides heaps of ways to identify users and many of those ways involve piercing a user's privacy, and if that is the only way, I will do what I do now (optional email registration). I just want a way for my app to know if a user already is registered in my system across installs without having to interview the user (username/password, email address, third-party OAuth, etc).
My main reasons are:
I don't want support requests from users who orphaned their content after a reinstall; and
I don't want to host lots of orphaned content.
Have a look at Firebase Authentication. It's quite seamless and does not require much effort to incorporate. Also it does not feel intrusive or cumbersome to the end user.
Here is a video tutorial by Google.
EDIT:
In case your users are sure to have a cellular device with a phone number, you can use AccountKit. It is also what they call OTA (One Time Authentication). AccountKit uses just the users phone number to verify and validate users.
EDIT:
Firebase Authentication now features 'Phone Verification' which is similar to AccountKit mentioned above. Both are good services. However, Firebase phone verification lets you make your own UI from scratch (which means a lot better control than AccountKit). Also, if you don't want to make your UI, you can always use FirebaseUI
i have implemented something that seems little similar to your thing by push notification , i can get error if user uninstalled my app(and from the registration id i get the user) , and if he re installed he obtain a new registration id , and try to get the user UUID for different devices
I think the simplest way would be using UUID and storing the hash on sharedPreferences. You should generate the UUID as earlier as possible in your app.
sharedPrefs = context.getSharedPreferences(APP_SHARED_PREFS,Activity.MODE_PRIVATE);
if (sharedPrefs.getString("YOUR-KEY-TO-THE-UUID") == null || "".equals(sharedPrefs.getString("YOUR-KEY-TO-THE-UUID"))){
prefsEditor = sharedPrefs.edit();
prefsEditor.putString("YOUR-KEY-TO-THE-UUID", UUID.randomUUID().toString());
prefsEditor.commit();
}
I think that the best way would be implementing login with Google or Facebook. This is quite seamless for users, safe enough (as Google and Facebook considered trusted), you do not need to implement your email registration and you will have identity across devices.
If your app is Android only and you'd like to provide identity without any account creation for the user, I believe using Google Account name/id is the best choice (Accessing Google Account Id /username via Android) since you have to use Google Account on Android phone (unless you root it, delete Google Play Services etc).
If you'd like to only address the first point of your question (identify after reinstall) there's a Device Id -Secure.getString(getContext().getContentResolver(), Secure.ANDROID_ID);
though it's not 100% reliable (f.e Factory Reset resets this value)
The standard for achieving this sort of functionality is through the use of JSON web tokens (JWT) in conjunction with standard restful api traffic.
Assuming your android application interacts with a RESTful api for all crudlike operations and business logic, then using a JWT as an authentication identifier to your api can work quite well. You can embed information in each JWT allowing you to identify whatever you like (the user id in the database, the device id of whereve the user logged in from, etc). A JWT is essentially a datastructure allowing you to store information to be used by the API.
Some basics for how this works:
Getting the JWT into the app: A user logs in to the application using their username/password. The
api then returns an encrypted JWT to be used by the client for all future requests. Don't try to do
the encryption yourself. Any language that can handle serving an api
will have libraries for this.
Using information in the JWT: The JWT is itself a datastructure. For example, it might look like this:
{
user_id: 1,
device_id: 44215,
device_os: android,
}
Your api will decrypt the JWT when it is supplied for
authentication via the request header, and then have that information available in the
context of the session.
If you provide the language used by your api then I might be able to recommend a library.
I will conclude by referring to the final requirement you submitted which states essentially that you do not want to have to interview the user across installs. If I understand your meaning, that you want a user to be able to simply install the application and begin using it without supplying authentication credentials, then there is no way to achieve that securely. You might be able to come up with a hackish way to get it to work, but it will be fundamentally insecure.
i need to achieve that, show the last wall publications of a programatically given user.
But i need to do it without login on facebook, and without using Oauth, without registering my app on facebook.
It is possible? i can't find the way to do it :S
To get any user information from Facebook you will need to create an application. To get private user data such as their last wall post, they will need to be logged into Facebook and authenticate with your application.
There are only a few things you can get without an access token from the user. It also depends on what security the user has set up. I don't know the reasons for not registering your app but its a simple process.
User Object
https://developers.facebook.com/docs/reference/api/user/
You can use the following to get the public feed https://graph.facebook.com/markzuckerberg/feed
Essentially it sounds like you want to get data from the Facebook API without using the Facebook API. This is not going to work very well.
You could access a user's posts, if their visibility was set to Public, using any access token (e.g. one you create using the Graph Explorer tool) but without knowing the user's uid, how will you know which user's posts to request?
Realistically you need them to authorise your app before you can get their uid, and by that time you could just use that same authorisation to access their public posts without needing any 'hacky' workarounds.