How to use Steam (OpenId) to login into my Firebase powered Flutter app? - flutter

I'm building a Flutter app and I want users to be able to login through Steam (OpenId).
The app is powered by Firebase.
I'm pretty new to the whole OpenId world and I've read into it but I'm still not getting it.
I found that Firebase Supports signinWithCustomToken so I think I should get the Steam OpenId to get me one of those.
I also found two packages which might help me but I couldn't get those to work either:
https://pub.dev/packages/openid_client
https://pub.dev/packages/steam_login
If tried the following sample from the openid_client package:
_authenticate(Uri uri, String clientId, List<String> scopes) async {
try {
var issuer = await Issuer.discover(uri);
var client = Client(issuer, clientId);
print('CLAIMS:');
print(issuer.claimsMap);
urlLauncher(String url) async {
if (await canLaunch(url)) {
await launch(url, forceWebView: true);
} else {
throw 'Could not launch $url';
}
}
var authenticator = Authenticator(client,
scopes: scopes, port: 4000, urlLancher: urlLauncher);
var c = await authenticator.authorize();
closeWebView();
print(await c.getUserInfo());
}catch (err) {
print(err);
}
}
But I have no idea what to give as the uri, clientId and scopes.
For the uri I've tried https://steamcommunity.com/openid but when I try this I'm getting an error that it tried to Json.parse a xml response.
I've also tried the example for the steam_login package here, but that does nothing and doesn't feel like it should work within a Flutter app (even though the package states it Flutter compatible).
So if anybody could explain to me how I could achieve this with a working sample that would be great.
If I get this to work I'm planning on creating a tutorial/guide for it for others.

Related

Why do I get a null username when using Apple Sign In in my Flutter app?

I am trying to implement the Apple social login within my Flutter IOS App. I succeed to successfully connect, but in the credential received it seems there Is no personal information in it such as:
The username: which is null
The email: I only get the iCloud address, even when I select a personal email when signing in.
I am using firebase_auth: ^3.7.0
here is my code for connecting with apple:
signInWithApple() async {
final appleProvider = AppleAuthProvider()
..addScope("email")
..addScope("fullName");
try {
await _auth.signInWithProvider(appleProvider).then((credential) async {
print(credential.toString());
});
} on FirebaseAuthException catch (errorMessage) {
print(errorMessage);
}
}
I have also attached the credential I get from this code.
[![received credentials][1]][1]
[1]: https://i.stack.imgur.com/fBKXn.png
Do you have any idea of what is going wrong ?

Flutter Dynamic linking not available for web apps?

My Use Case:
Users in my app can create lists of items. I want the users to be able to share a link to one of their lists.
I want individuals who click the shared link to see the list of items in a web browser and not need the app installed.
Create the Dynamic Link
The first thing I need to do is create a dynamic link for a user to share. I struggled with this at first and then looked at this question here: Flutter - How to pass custom arguments in firebase dynamic links for app invite feature?
After looking at that I build my own class like so:
class PackDynamicLinkService {
Future<Uri> createDynamicLink({required String packID}) async {
final DynamicLinkParameters parameters = DynamicLinkParameters(
// This should match firebase but without the username query param
uriPrefix: 'ttps://appName.app/p',
// This can be whatever you want for the uri, https://yourapp.com/groupinvite?username=$userName
link: Uri.parse('https://appName.app/p?pack=$packID'),
androidParameters: const AndroidParameters(
packageName: 'com.test.demo',
minimumVersion: 1,
),
iosParameters: const IOSParameters(
bundleId: 'com.test.demo',
minimumVersion: '1',
appStoreId: '',
),
);
final dynamicLink = await FirebaseDynamicLinks.instance.buildShortLink(
parameters,
shortLinkType: ShortDynamicLinkType.unguessable,
);
return dynamicLink.shortUrl;
}
}
I then called that function in my app and I am able to get a URL that looks like this: https://appName.app/p?pack=lVeSBUHoLX52zPqAiB9A
So far so good. Now I just need to click the link and read the parameter $packID that I passed to it inside my web app. Then I can route them to the correct view and display the list.
Processing Dynamic Link
in my marin.dart I tried to retrieve the params with:
//get link stuff
final PendingDynamicLinkData? initialLink =
await FirebaseDynamicLinks.instance.getInitialLink();
if (initialLink != null) {
final Uri fullLink = initialLink.link;
print(fullLink.queryParameters['pack']);
}
but when I upload to firebase hosting to see if this code works for testing, I get this error:
Uncaught MissingPluginException(No implementation found for method
FirebaseDynamicLinks#getInitialLink on channel
plugins.flutter.io/firebase_dynamic_links)
After doing some more research it seems that firebase_dynamic_links package may not be available for web? So does that mean my original use case is not possible with flutter at this time?
You would want to take the link received and parse it using something like:
var PendingDynamicLinkData? initialLink =
await FirebaseDynamicLinks.instance.getInitialLink();
if (kIsWeb) {
String link = Uri.base;
initialLink = await
FirebaseDynamicLinks.instance.getDynamicLink(Uri.parse(link));
}
if (initialLink != null) {
final Uri fullLink = initialLink.link;
print(fullLink.queryParameters['pack']);
}
Here, we are checking if its a web app and then we can parse the dynamic link and get the info for it. We just check for the Uri that was used in our web app.

Calendar clientViaUserConsent it gives me Authorization Error while creating event

clientViaUserConsent opens URL in browser but it said invalid request. this URL is generated internally from lib. I had double-checked my ClientId for both platforms but still face issues for getting AuthClient for create a calendar event.
I used the below packages to create events in the google calender.
googleapis: ^8.1.0
googleapis_auth: ^1.3.0
static final androidClientId = ClientId('xxxxxxxx.apps.googleusercontent.com');
static final iOSClientId = ClientId('xxxxxxx.apps.googleusercontent.com');
final _clientID = Platform.isAndroid ? EventProvider.androidClientId : EventProvider.iOSClientId;
final _scopes = [CalendarApi.calendarScope];
clientViaUserConsent(_clientID, _scopes, prompt).then((AuthClient client) {
var calendar = CalendarApi(client);
}
void prompt(String url) async {
print(" => $url");
if (await canLaunch(url)) {
await launch(URL);
} else {
throw 'Could not launch $url';
}
}
I am referring to this article for creating an event in google calendar.
https://blog.codemagic.io/google-meet-events-in-flutter/
https://medium.com/flutter-community/flutter-use-google-calendar-api-adding-the-events-to-calendar-3d8fcb008493
You are seeing that error because the app hasn't been verified. If you are the app developer I advise you to check the App Verification FAQ to learn more about the verification steps. If you aren't the developer, you could try to enable the less secure app access but please be mindful of the consequences:
Less secure apps can make it easier for hackers to get in to your account, so blocking sign-ins from these apps helps keep your account safe.

Flutter chatbot HandshakeException when accessing DialogFlowAPI

The bot is built using DialogFlow + Flutter and the package used is https://pub.dev/packages/dialog_flowtter version 0.3.0-nullsafety.0
The app works relatively fine as long as you type, but as soon as you stop writing it gives the exception mentioned. I am located in Romania, eastern Europe, I have read somewhere that it might be because of the location and others mentioned about the https certificate. Currently I have used correctly the auth.json file as far as I know. Thanks in advance
The exception is throwed from the file dialog.dart.
async {
if (_client == null) await _updateHttpClient();
var body = HttpUtil.getBody(
queryParams: queryParams,
queryInput: queryInput,
audioConfig: audioConfig,
);
var response = await _client.post(
'$kDialogFlowUrl/$kDialogFlowApiVersion/${HttpUtil.getFormatedSession(projectId, sessionId)}:detectIntent',
body: jsonEncode(body),
);
Exception
Same exception but in code

How to get auth code for Google OAuth using the Mongo Stitch React-Native SDK?

From the docs it seems like there is no other way to sign-in using Google other than using the GoogleCredential constructor which takes an authCode as a mandatory parameter, how should I get it?
For an example of [[loginWithRedirect]], see Facebook Authentication
Also, there are multiple references in the docs to a function called loginWithRedirect, but they don't link anywhere and there is no property in the auth object called loginWithRedirect.
Indeed, the RN and server SDKs do not support the redirect concept. You have to get your own authCode.
Stitch's GoogleCredential constructor just expects a valid server auth code so that the Stitch service can use offline access.
Use a third-party OAuth module
I had no luck using the official google-auth-library SDK with RN. I was able to make it work (on iOS, at least -- haven't tried Android, yet) with react-native-google-signin from react-native-community. The installation process is a bit involved, so be sure to follow their instructions carefully!
I will show how I used this specific library to sign in. Hopefully this information can be applied to other OAuth libraries and other Authentication providers (e.g. Facebook).
Configure GoogleSignin
The webClientId must be specified and must match the Client ID under the Google Oauth2 configuration on the Stitch UI (see screenshot). The iosClientId is found in the GoogleService-Info.plist you download after following these steps. Finally, set offlineAccess to true.
If you use the Google iOS SDK directly or another library, note that webClientId is called serverClientID and iosClientId is simply called clientId.
Here's my configure code (see my complete App.js file):
componentDidMount() {
// ...
GoogleSignin.configure({
webClientId: '<id>', // from Stitch UI > Users > Providers > Google
offlineAccess: true,
iosClientId: '<id>', // CLIENT_ID in GoogleService-Info.plist
});
}
Render GoogleSigninButton
react-native-google-signin provides a nice button to use, which I rendered out (see screenshot):
const loginButton = <GoogleSigninButton
style={{ width: 192, height: 48 }}
size={GoogleSigninButton.Size.Wide}
color={GoogleSigninButton.Color.Dark}
onPress={this._onPressLogin}
disabled={this.state.isSigninInProgress}
/>
Give Stitch the serverAuthCode from GoogleSignin
My _onPressLogin function uses GoogleSignin to get the serverAuthCode. It then passes that code to Stitch:
_onPressLogin = async () => {
// They recommend calling this before signIn
await GoogleSignin.hasPlayServices();
// Call signIn to get userInfo
const userInfo = await GoogleSignin.signIn();
// Check if serverAuthCode was received -- it will be null
// if something wasn't configured correctly. Be sure to
// log out after changing a configuration.
const {serverAuthCode} = userInfo;
if (serverAuthCode === null) {
throw new Error('Failed to get serverAuthCode!');
}
try {
// Pass serverAuthCode to Stitch via GoogleCredential
const user = await this.state.client.auth.loginWithCredential(new GoogleCredential(serverAuthCode));
console.log(`Successfully logged in as user ${user.id}`);
this.setState({ currentUserId: user.id });
} catch(err) {
console.error(`Failed to log in anonymously: ${err}`);
this.setState({ currentUserId: undefined })
}
Logging out
I found I had to log out several times while testing (and figuring out which client IDs to use where), or else serverAuthCode would come back null. It was good to have the logout button visible at all times. My logout code looks like this:
_onPressLogout = async () => {
await GoogleSignin.revokeAccess();
await GoogleSignin.signOut();
const user = await this.state.client.auth.logout();
console.log(`Successfully logged out`);
this.setState({ currentUserId: undefined })
}
I hope this helps!