Update (20160521): Firebase has just released a major update for its Firebase Authentication product, which now allows a single user to link accounts from various supported providers. To learn more about this feature, read the documentation for iOS , Web, and Android . The answer below is for historical reasons.
The core Firebase service provides several authentication methods: https://www.firebase.com/docs/security/authentication.html
At its core, Firebase uses secure JWT tokens for authentication. Everything that leads to the creation of a JWT token (for example, using the JWT library on your own server) will work to authenticate your users in Firebase, so you have complete control over the authentication process.
Firebase provides the Firebase Simple Login service, which is one of the ways to generate these tokens (this is provided by our Facebook, Twitter, etc. auth). It is intended for general authentication scenarios, so you can quickly start and run without a server, but this is not the only authentication method and is not intended for a comprehensive solution.
Here is one approach for allowing login with multiple providers using Firebase Simple Login:
- Store one canonical user identifier for each user and a mapping for each provider identifier to one canonical identifier.
- Update your security rules to match any of the credentials on this user account, and not just one.
In practice, security rules may look like this if you want to enable Twitter and Facebook authentication (or allow the user to create an account with one, and then add another):
{ "users": { "$userid": { // Require the user to be logged in, and make sure their current credentials // match at least one of the credentials listed below, unless we're creating // a new account from scratch. ".write": "auth != null && (data.val() === null || (auth.provider === 'facebook' && auth.id === data.child('facebook/id').val() || (auth.provider === 'twitter' && auth.id === data.child('twitter/id').val()))" } }, "user-mappings": { // Only allow users to read the user id mapping for their own account. "facebook": { "$fbuid": { ".read": "auth != null && auth.provider === 'facebook' && auth.id === $fbuid", ".write": "auth != null && (data.val() == null || root.child('users').child(data.val()).child('facebook-id').val() == auth.id)" } }, "twitter": { "$twuid": { ".read": "auth != null && auth.provider === 'twitter' && auth.id === $twuid", ".write": "auth != null && (data.val() == null || root.child('users').child(data.val()).child('twitter-id').val() == auth.id)" } } } }
In this example, you save one global user ID (which can be any of your choice) and maintain a mapping between the authentication mechanisms of Facebook, Twitter, etc. in the user master record. After logging in for each user, you will retrieve the user master record from user mappings and use this identifier as the main repository of user data and actions. The above also limits and validates the data in user mappings, so that only the corresponding user who already has the same Facebook, Twitter, etc. user ID can write it. Under / users / $ userid / (facebook-id | twitter -id | etc. identifier).
This method will allow you to quickly get up and work. However , if you have a difficult precedent and want full control over the auth experience, you can run your own custom code on your servers . There are many useful open source libraries you can use for this, such as everyauth and passport .
You can also authenticate using third-party service providers. For example, you can use Singly , which has a huge number of integrations out of the box, without having to write any server code.