Firebase + Flutter : get platform user used to sign in - firebase

I have an app with 3 sign in methods: Google, Facebook & mail.
I want to show the users that are signed in with mail a different screen.
Is it possible to get the sign in method form the package firebase authentication?
I know I can fix this by using firestore & checking if a statement is true or false. But that will cost me a read every time a user opens the app...

This seems to be what you want: https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseUser.html#getProviderData()
In my app where I use Google logins only, I have firebaseUser.providerData[1].providerId == 'google.com'.
Btw, firebaseUser.providerData[0].providerId == 'firebase'.
I guess you could check them all and look for what providers you get for different kinds of users.
Edit: here's what I get when logging in with e-mail: https://postimg.cc/BXWGGN6h

Firebase has a special property providerId. But, as mentioned #GazihanAlankus it always returns firebase.
And, the property firebaseUser.providerData[1].providerId sometimes not exists (for example when user used anonymous login).
So, we should use appropriate approaches, for example:
FirebaseUser user = await _firebaseAuth.currentUser();
if (user.providerData.length < 2) {
// do something
}
else {
print(res.providerId);
}
The list of values, that are returned by property providerId:
EmailAuthProviderID: password
PhoneAuthProviderID: phone
GoogleAuthProviderID: google.com
FacebookAuthProviderID: facebook.com
TwitterAuthProviderID: twitter.com
GitHubAuthProviderID: github.com
AppleAuthProviderID: apple.com
YahooAuthProviderID: yahoo.com
MicrosoftAuthProviderID: hotmail.com
I got this list from the cool research here What is the full list of provider id's for firebase.UserInfo.providerId?

In my app I used
FirebaseAuth.instance.currentUser.providerData[0].providerId == 'google.com'.,
cause providerData[1] doesn't contain any value

For anyone reading this in 2022, Firebase now has nice new docs for Flutter and in it they have this, which I personally found super useful:
if (user != null) {
for (final providerProfile in user.providerData) {
// ID of the provider (google.com, apple.cpm, etc.)
final provider = providerProfile.providerId;
// UID specific to the provider
final uid = providerProfile.uid;
// Name, email address, and profile photo URL
final name = providerProfile.displayName;
final emailAddress = providerProfile.email;
final profilePhoto = providerProfile.photoURL;
}
}
Source: Firebase documentation

But that will cost me a read every time a user opens the app. THIS IS TRUTH!
Alternatively, you can create your own app DB using SQFLite, and create only one table (user) in that, having a field of signUpMethod having possible values are google, facebook and mail. Whenever you opens the app, first check that in your db, if this is mail, redirect to another screen which you want, else call firebase service
Cheers!

Related

Firebase & Flutter (on Android) - MessagingToken is null

I'm running into trouble with some of my app's subscribers. We recently introduced the ability to send out notifications to our users using FirebaseMessaging. I should also mention that the app is on Android only.
Here is a brief section of code that we are running
updateUser(Userx user) async {
var messagingToken = await FirebaseMessaging.instance.getToken();
var packageInfo = await PackageInfo.fromPlatform();
user.messagingToken = messagingToken!;
user.appVersion = packageInfo.version;
await Users.updateUser(user);
}
It turns out that the FirebaseMessaging.instance.getToken() sometimes returns null and I can't figure out why that would be the case. The documentation also doesn't say much.
Could this be device specific? Maybe a user-setting to not allow any in-app messages?
A potential workaround is of course to null-check the token and simply accept it being null but I would like to understand the reasons behind that.
I found one more method that could be helpful, but I'm unsure about it.
Call FirebaseMessaging.instance.isSupported() first and act based on the result.

Flutter dynamic links test

Edited Question :
I have an issue with Firebase Dynamic Links Packag , My goal is getting know if new user installed and opend my app for first time to give him a rewards like 10 point . I tried to search everywhere but no answer,in firebase website there is option to know if user install for first time.
My Goal is : Getting value for first time install & how to debug this code ?
initDynamicLinks when app Lanched :
void initDynamicLinks() async {
FirebaseDynamicLinks.instance.onLink(
onSuccess: (PendingDynamicLinkData dynamicLink) async {
final Uri deepLink = dynamicLink?.link;
if (deepLink != null) {
Navigator.pushNamed(context, deepLink.path);
}
},
onError: (OnLinkErrorException e) async {
print('onLinkError');
print(e.message);
}
);
final PendingDynamicLinkData data = await FirebaseDynamicLinks.instance.getInitialLink();
final Uri deepLink = data?.link;
if (deepLink != null) {
Navigator.pushNamed(context, deepLink.path);
}
}
.
You're mixing two things here.
The First-opens tab gives you the number of unique users who clicked on your Firebase Dynamic Link for the first time.
If you want to know how many unique users used your app, by clicking the Firebase Dynamic Link or not to get to your app, you have to implement the Firebase Analytics plugin to your app.
This way you'll get access to Dashboards showing you how many Unique users you have.
EDIT
Reading your comment, looks like your question is not related to your problem.
What you want here is to attribute rewards for users who invited their friends thanks to a referral link.
Since I never implemented this witout a dedicated backend, the only thing I can share is a use-case I used some time ago explaining the logic to follow to implement it.
https://firebase.google.com/docs/dynamic-links/use-cases/rewarded-referral
EDIT 2
The logic explained in the documentation is the following :
1- Generate a Dynamic Link for UserA.
2- UserA sends the Dynamic Link to someone (called UserB).
3- When UserB starts the app from a Dynamic Link, retrieve the referral informations in the app (to retrieve UserA's informations)
4- Call a route on your backend to attribute the reward to UserA (and check if UserB is really a new user in your database).
The point is, you shouldn't manage a referral/referrer relationship on the client's side (it would be way too easily abused/hacked).
It's the job of a backend (or cloud function) to manage this.
Once you have received the link clickthrough in your app use the google_analytics package to log an event.
Related thread here:
Flutter log event with google analytics
To be honest i have never used Firebase Dynamic Links , But if your Goal is to Achieve a first open or login token , you can always use the Sharedpreferences package , in my case iam using it to navigate to different pages passed on the first login value .
i think that Sharedpreferences is more reliable and easier than what you are trying to achieve with firebase
UPDATE:
what you actually want to do is make a firebase collection with IMEI numbers , when there is a new IMEI that means a new user , when that IMEI is in your collection that means that the app is not installed for the first time ,
you can use this package imei_plugin to get IMEI number and store it on firebase

Firebase Auth: Is it possible to see user's Twitter ID?

I have just implemented the Twitter login to my Firebase web app. When the user successfully login, I'd like to see the user's Twitter ID (to enable Twitter-based communication among users).
According to the document (https://firebase.google.com/docs/auth/web/manage-users), the provider specific information is under providerData of the user info.
Under the providerData, I see the following
displayName: "Satoshi Nakajima" (as I expected)
email: null (as I expected)
phoneNumber: null (as I expected)
photoURL: "https://abs.twimg.com/..." (as I expected)
providerId: "twitter.com" (of course)
uid: "1129128..." (what is this?)
The uid seems like a unique id, but it is different from the Twitter ID we usually use, such as #snakajime (which is mine).
I am wondering why I don't see the Twitter id here. Am I missing something? Is there any API to get the Twitter ID from this strange uid?
You can actually get it immediately after sign-in, via AdditionalUserInfo.
Here is an example with the web API:
firebase.auth().signInWithPopup(new firebase.auth.TwitterAuthProvider())
.then((userCredential) => {
// Get the Twitter screen name.
console.log(userCredential.additionalUserInfo.username);
})
.catch((error) => {
// An error occurred.
});
As far as I know, the screen name you are looking for is not included as part of the Twitter OAuth provided through Firebase, but the uid that you have found is indeed the user's twitter user ID.
Using this ID you can use the Twitter API to get details about the user by passing it to the twitter API users/show endpoint. Since you plan on providing Twitter based communication, you will likely need to use this API anyway.
e.g.:
GET https://api.twitter.com/1.1/users/show.json?user_id={the_uid_from_provider_data}
RESPONSE:
{
"id": {the_uid_from_provider_data},
"id_str": "{the_uid_from_provider_data}",
"name": "Snakajime",
"screen_name": "snakajime", // <--- Here is the screen name you are looking for
...
}

Cannot Create User Profile in Firebase

First off, thanks for taking the time; this is my first question posted!
I'm in the middle of coding my first mobile application in React Native: a stats managing App for my fraternity. Right now, I would like an admin user to be able to add other users to the app and set their initial profile information (first name, last name, position, dues paid etc).
Once they submit the details, the code below tells firebase to create a new user using the provided email and password, then adds their other profile information under the user parent in the Realtime Database.
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(() => {
console.log(key);
firebase.database().ref('/ChapterName/users/' + key)
.set({ firstName, lastName, rank, position, goodStanding, dues, communityService, chapters, mixers, brotherhoods });
})
The JSON tree created can be seen here: Firebase Tree
My problem is that when the new user logs in, I cannot find a way to access their profile information...ideally, I would set the key of each child under 'user' to the user's email: that way they could login and I could match their email to the key of their profile info and fetch it that way. Unfortunately, keys must be UTF-8 encoded and don't allow for me to include '# or .'
Does anyone know a way around this? I feel as if the firebase Admin API could be a solution but I can't seem to wrap my head around it.
Inside react-native with firebase, if they user already login and you already integrate firebase with redux, you can access the current user information inside redux using this line
state.firebase.profile
as per my suggestion, I think it's best for to integrate
react-native app + react-native-firebase + react-redux-firebase
thus, you dont have to use web firebase function as it's already exist in props.
if you need to update the profile after user already created you can use something like this
this.props.firebase.auth().createUserAndRetrieveDataWithEmailAndPassword(email, password).then((user) => {
this.props.firebase.updateProfile(
{
name: 'Hazim',
age: 24,
mode: 'Rampage'
}
)
}).catch((error) => {
//Error value
})
and inside any component, you can get current user info with connect function like this.
class Home extends Component {
}
export default compose(
firebaseConnect(),
connect( state => {
profile: state.firebase.profile
})
)(Home)

Get Username of Current Realm SyncUser in Swift

Realm Swift 2.0.2, Swift 3
I'd like to display the username of the current Realm SyncUser in my UI. I know I can get the unique ID of a user like this:
let user = SyncUser.all().first
print(user?.identity) //a7f84g203fd18... etc.
...but is there a way to get the user's username? I don't see anything in the docs about it.
Currently there is no way to get username from SyncUser: SyncUser doesn't have username at all, it's just one of the credentials that could be used for authentication.
There is also a related issue at https://github.com/realm/realm-mobile-platform/issues/12
My current solution is to save to UserDefaults the user's email/username when they sign up:
let defaults = UserDefaults.standard
defaults.set(self.email.text!, forKey: "userEmail")
...and then reference it later where I need it in my app:
//Show username/email
accountStatus.text = defaults.string(forKey: "userEmail")

Resources