Steroids.js + Firebase Twitter Authentication Hangs on White Screen - javascript

I have a Steroids app running on iOS, and have been having trouble successfully authenticating with Firebase.
My authentication function looks like this, per the Firebase API guide to authenticating with Twitter.
var ref = new Firebase("https://xxx.firebaseio.com/");
var sync = $firebase(ref);
$scope.loginWithTwitter = function() {
ref.authWithOAuthPopup("twitter", authHandler);
};
function authHandler(error, authData) {
if(error) {
supersonic.logger.log("Login failed!" + error);
} else {
supersonic.logger.log("Authenticated successfully with payload: " + authData);
}
}
The above code when activated popups a window in the app, which after signing in says that it is redirecting back to the app. Then...
Here is a screenshot of the screen I'm stuck on:
http://wcet2.waketech.edu/sirhodes/ios.png
Clicking "Done" in the bottom left corner, outputs this to console:
Screenshot of return (I tried twice, hence the double message):
http://wcet2.waketech.edu/sirhodes/console.png
Important notes:
I am using AngularFire, not the plain javascript API for most of the app, excluding the authentication method.
I did check "Allow this application to be used to Sign in with Twitter" box in the Twitter App settings
I have set the consumer key and secret provided by, refreshed these values, and updated them in Firebase Forge.
Versions:
Angular : 1.3.14
Steroids: 3.5.10
Firebase: 2.2.1
AngularFire: 0.9.2
iPhone 5s iOS: 8.2
Link to similar redirect issue, but using the Ionic Framework

Related

Google SignIn SDK is failing by throwing error, A non-recoverable sign in failure occurred -catch error: React Native

I have been trying to integrate Social login in my react native project in which I was able to do facebook login successfully but it is failing to signin to google. react-native-google-signin library is used for google.
The code I have used.
componentDidMount() {
GoogleSignin.hasPlayServices({ autoResolve: true }).then(() => {
// play services are available. can now configure library
}).catch((err) => {
console.log("Play services error", err.code, err.message);
})
GoogleSignin.configure({
scopes: ["https://www.googleapis.com/auth/drive.readonly"], // what API you want to access on behalf of the user, default is email and profile
// iosClientId: <FROM DEVELOPER CONSOLE>, // only for iOS
webClientId: "xxx", // client ID of type WEB for your server (needed to verify user ID and offline access)
// offlineAccess: true // if you want to access Google API on behalf of the user FROM YOUR SERVER
//hostedDomain: '' // specifies a hosted domain restriction
//forceConsentPrompt: true // [Android] if you want to show the authorization prompt at each login
//accountName: '' // [Android] specifies an account name on the device that should be used
})
.then(() => {
// you can now call currentUserAsync()
});
_signIn = async () => {
try {
await GoogleSignin.hasPlayServices(
)
const userInfo = await GoogleSignin.signIn();
console.log('User Info --> ', userInfo);
this.setState({ userInfo });
} catch (error) {
console.log('Message', error.message);
if (error.code === statusCodes.SIGN_IN_CANCELLED) {
console.log('User Cancelled the Login Flow');
} else if (error.code === statusCodes.IN_PROGRESS) {
console.log('Signing In');
} else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
console.log('Play Services Not Available or Outdated');
} else {
console.log('Some Other Error Happened');
}
}
};
The error response:
Message: A non-recoverable sign in failure occurred -catch error
I know, I am very late to answer this question. I just faced the same issue and spent almost 4-5 hours to resolve this.
The solution that I have found:
"It starts working when I have added Support Email on Firebase"
I think it's not the app or configuration issue. It may be a firebase issue that should be reported and nowhere in the doc.
Apk link https://drive.google.com/file/d/1FNFBX-M7PQC6ShCC3KSuOH2E57YGPj6H/view?usp=sharing
go to android folder ./gradlew signingReport Take the SHA1 of Task
:app:signingReport, Variant: debugAndroidTest, Config: debug Update
add fingure print sha1 in your project inside firebae.console.google.com
and download again google-service.json file in your project
[Error: A non-recoverable sign in failure occurred]
1. add support email to solve this error
2. and wait 5 minutes your google login will be working fine
Following here
cd ./android && ./gradlew signingReport
Take the SHA1 of Task :app:signingReport, Variant: debugAndroidTest, Config: debug
Update it the Firebase Console under Project Settings, Android app, add the SHA1
Download the google-services.json, put it in ./android/app
Go to Authentication, then Sign-in method, then press Google
Take the Web client ID and use that for your GoogleSignin.configure({ webClientId: ... });
This Web client ID should be the same as listed in https://console.developers.google.com/apis/credentials?project=<your_project_id> -> Credentials -> OAuth 2 Client ID -> Web Client
run gradlew signingReport in the android folder and check all the sha1 listed and if you are using firebase then make sure that all the distinct sha1 found in the list is added to the firebase project then download the google-services.json again replace it with the old one in you project and run cd android && gradlew clean and build your project again
That's due to the clientId.
In google developer console, When you configure the project for webClientID, instead of creating a new project choose an existing one, i.e create the project first and then choose it for creating credentials.
Create a new project first as of in below picture
then choose that project from the list to create credentials
It worked for me.
And coming to sign in configuration
GoogleSignin.hasPlayServices({ autoResolve: true }).then(() => {
})
.catch((err) => {
console.log("Play services error", err.code, err.message);
})
GoogleSignin.configure({
scopes: ["https://www.googleapis.com/auth/userinfo.profile"],//scopes as you need
webClientId: "***(Your clientId)",
//iosClientId: <FROM DEVELOPER CONSOLE>, // only for iOS
//offlineAccess: true, //(give it true if you need serverAuthCode i.e cross client authorisation)
//hostedDomain: ''
//forceConsentPrompt: true // [Android] if you want to show the authorization prompt at each login
//accountName: ''
})
You need to add the support email.
For that:-
Go to console.firebase.google.com
Select <YOUR_PROJECT> project.
Go to project settings
Under General tab scoll down to add support email. Add your email over there.
In my case, I've used the package name for my test app (ex. com.loginTest). After making my package name unique, I was able to solve this problem!
I searches and came across the following steps
Enable OAuth on https://console.developers.google.com
Copy and paste your SH1 while enabling
Enable Google sign in on firebase authentication
Use Oauth Client_Id instead of your WebClient ID
This fix could also help:
Go to console.developer.google.com
Select the project.
Go to Credentials.
Switch to O Auth Consent screen.
Change the app name and fill email id (optional)
Save at the bottom
Try logging in now and it should work.
Add support email in firebase and it will start working
Android
Make sure to follow these guidlines:
https://rnfirebase.io/auth/social-auth#google
https://github.com/react-native-google-signin/google-signin/blob/master/docs/android-guide.md
Dont forget to generate SHA-Keys and set them in your Firebase Console
with Simulator:
When testing on an Android Simulator, make sure GooglePlayServices are enabled.
To prove this, add a few more lines to your SignInMethod:
const signInWithGoogle = async() => {
// Wrap with try catch
try {
await GoogleSignin.hasPlayServices({ showPlayServicesUpdateDialog: true }); // <-- Add this
const { idToken } = await GoogleSignin.signIn();
const googleCredential = auth.GoogleAuthProvider.credential(idToken);
return auth().signInWithCredential(googleCredential);
} catch (error) {
// This will show you if GooglePlayServices is missing
console.log('With high probability, GooglePlayServices are missing on this device');
return;
}
}
The problem can reside in the app name, change it to a random (or unique) one (a name you're sure nobody else chosen), or generate a new app with a random (or unique) name.
This is because the generated React Native apps come all with the same SHA-1 fingerprint, and because Google prevents that two different Android apps registered on their cloud share the same pair of App name and SHA-1 fingerprint, you got this error (and surely you have already seen a warning on the Firebase console when creating the App!).
Source: https://support.googles.ltd/firebase/answer/6401008?hl=en&ref_topic=6399725
A complete guide to use Google signin on a React Native app: https://github.com/ubugnu/reactnative-google-signin
i don't know why but i got this error on emulator with Android 28
when i create another emulator with api 31 the error fixed!
IF YOUR APP ARE ON RELEASE:
On project, go to /android, then run ./gradlew signingReport
Copy SHA1 of release and debugTest (very important)
Go to https://console.firebase.google.com
Place all SHA1
Download Google Services JSON and put it on android/app
Build your app and run!
This worked for me.

Redirection to a mobile app from the webview of the app itself in React Native

I'm building an android application which requires authentication from an external auth provider.So I'm using react-native-oauth package to handle this.
The redirect_uri defined is a deep link which should ideally open my app itself after successful authentication.But the WebView seems to not handle this redirection and I'm getting response as 404-page not found.
This is the service that I have written to handle the auth:
const manager = new OAuthManager('<app_name>')
manager.addProvider({
'provider': {
auth_version: '2.0',
authorize_url:'<auth-url>',
access_token_url: '<auth-url>/token',
callback_url: 'http://localhost/provider',
}
});
manager.configure({
provider: {
client_id: '<id>',
client_secret: '<secret>',
redirect_uri: '<redirect-uri>' //DEEP LINK HERE
}
});
module.exports = {
authManager: () => {
manager.authorize('<provider>')
.then(resp => console.log(resp))
.catch(err => console.log(err));
}
}
Also I have defined my intent-filter as specified in the Android docs on how to declare the deep links for your apps.The deep link works fine when opened with Linking.openURL() from the app components.
Any help in this is much appreciated.
You can't directly set redirect_uri to your mobile app ( because most auth providers doesn't support custom OAuth scheme ).
But you can create some web page that will accept redirect from OAuth providers and will open your app ( and send all redirect params, like token ).
For example you create page https://example.com/oauth/, and set callback_url to https://example.com/oauth/XXXXX_provider, so when user will be redirected to page https://example.com/oauth/XXXXX_provider&token=xxx it will open you app using appName://example/oauth/google?token=xxx
You can handle appName://example/oauth/google?token=xxx using Deeplink ( it will open your mobile app when it is installed on device )
Example of page to handle redirects:
<html><head></head><body>
<p>Please wait while we redirect you to Your APP NAME...</p>
<p>Open appname</p>
<script>
var redirectToApp = function() {
var scheme = "appnameapp";
var openURL = "appname" + window.location.pathname + window.location.search + window.location.hash;
var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
var Android = /Android/.test(navigator.userAgent);
var newLocation;
if (iOS) {
newLocation = scheme + ":" + openURL;
} else if (Android) {
newLocation = "intent://" + openURL + "#Intent;scheme=" + scheme + ";package=com.appnameapp;end";
} else {
newLocation = scheme + "://" + openURL;
}
console.log(newLocation)
window.location.replace(newLocation);
}
window.onload = redirectToApp;
</script>
</body></html>
WebView by default doesn't share cookies/session data with Safari/Chrome. So it is not ideal for login flow since it doesn't use the existing logged in session in Chrome/Safari.
Expo provides a WebBrowser api that will open Safari/Chrome instead of webview. Note that it opens Safari/Chrome inside the app, instead of redirecting you the browser using Linking. So users always have a button in the browser to get back to your app.
You can use WebBrowser.openAuthSessionAsync(url) to open a secure session which shares cookie/session info with the native browser in the device.
Expo also provides another api called AuthSession that simplifies a lot of boilerplate and provides a simple api.

What oauthRedirectURL in openFB should look like, using a cordova app?

I came across this openFB plugin to make facebook requests without the sdk, that can be used in cordova,
I got it to log in the user in facebook, the thing is as oauthRedirectURL I end up in a white page, that says Success and I'm not sure how to get the user back to the app,
if (runningInCordova) {
oauthRedirectURL = "https://www.facebook.com/connect/login_success.html";
}
Question is,
What url can i use to point my app ?
User ends up in this screen after the login
-edit-
I found solutions like http://localhost.com/oauthcallback.html but I don't have a apache2 in the cordova environament..
-2nd edit-
This is my current code,
openFB.init({appId: 'xxxxxxxxyyyyyyyy'});
openFB.login( function(response) {
if(response.status === 'connected') {
alert('Facebook login succeeded, got access token: ' + response.authResponse.token);
} else {
alert('Facebook login failed: ' + response.error);
}
}, {scope: 'email'});
This the line of the lib that fills this value
if (runningInCordova) {
oauthRedirectURL = "https://www.facebook.com/connect/login_success.html";
}
I haven't used openFB before but I'm pretty sure it's based on the following docs:
https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.3
If you go to the section "logging people in" you'll see the following message:
redirect_uri. The URL that you want to redirect the person logging in
back to. This URL will capture the response from the Login Dialog. If
you are using this in a webview within a desktop app, this must be set
to https://www.facebook.com/connect/login_success.html.
When a FB user grants permissions to your App, it will be redirected to the url https://www.facebook.com/connect/login_success.html?access_token=new_token&...
What you have to do now is monitor this url and get the access token provided, which you should store with the fb user id in order to perform any API call.
Googling how to do this with openFB I found a thread at the openFB github repo that should help: https://github.com/ccoenraets/OpenFB/issues/20#issuecomment-49249483 (is not totally related but it provides some code you can use)
This should be the code that will allow you to monitor the URL (extracted from the code provided on the thread):
if (runningInCordova) {
loginWindow.addEventListener('loadstart', function (event) {
var url = event.url;
if (url.indexOf("access_token=") > 0) {
// Get the token
}
});
}
Once you have obtained the access token and stored in your database, you should redirect to any other place of your App.
I hope it helps.
Javier.

How to implement push notification support in Cordova app using Quickblox?

Apologies for such a basic question, but I really can't find any information on the subject.
The Quickblox Javascript SDK has some classes related to push notifications, and I have enabled them using chat_history and the alerting tab in chat. However what I don't understand is how to receive these notifications on the front end UI?
I don't have any code to share as I don't know where to start!
Any help would be truly appreciated, thank you.
There are modules to work with pushes:
QB.messages.tokens
QB.messages.subscriptions
QB.messages.events
To subscribe for pushes you have to do 2 things:
Create a push token using QB.messages.tokens
Create a subscription using QB.messages.subscriptions
Additional info can be found in REST API page http://quickblox.com/developers/Messages#Typical_use_.D1.81ases
Also you have to upload APNS and Google API key to QuickBlox admin panel.
This all needs if you are going to build Cordova app for iOS/Android
You need encode the message.
You need to make sure your mobile app would know to understand the decoded message.
For example,
sending push notification to android qb_user_id: 20290
(and from me - my qb_user_id: 12121):
function b64EncodeUnicode(str) {
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
return String.fromCharCode('0x' + p1);
}));
}
function send_push() {
var params = {
notification_type: 'push',
push_type: 'gcm',
user: {ids: [20290]},
environment: "production",
message: b64EncodeUnicode('{"message":"HELLO WORLD","user_id":12121,"device_type":"WEB","message_qb_id":"563a55a44cedaa83885724cf","message_type":"Text","send_status":"BeingProcessed","send_time":1446663588607}')
};
QB.messages.events.create(params, function(err, response) {
if (err) {
console.log("QB.messages.events.create::error:" +err);
} else {
console.log("QB.messages.events.create::response:" + response);
}
});
}
In this example, the mobile app is looking for a message in this format:
{"message","user_id","device_type","message_qb_id","message_type","send_status","send_time"}

I receive an "FirebaseSimpleLogin: An unknown error occurred" in Firebase when I try to log in with Twitter

Yesterday, I discovered Firebase and started to use it. I deployed an edited version (I just changed the CSS) of the chat app provided by Firebase, Everything went OK until I added Twitter Logging option. I couldn't authenticate my app with Twitter even though I followed these instructions and I activated "Sign in with Twitter" from Twitter Application Management Panel.
This is the code I'm using in my chat app to log in (anything else is related to Twitter logging in my code):
// instatiate the FirebaseSimpleLogin and monitor the user's auth state
var chatRef = new Firebase('https://ranchat.firebaseIO.com');
var auth = new FirebaseSimpleLogin(chatRef, function(error, user) {
if (error) {
// an error occurred while attempting login
alert(error);
} else if (user) {
// user authenticated with Firebase
alert('Welcome' + user.username);
} else {
// user is logged out
}
});
// attempt to log the user in with your preferred authentication provider
$('#twlog').click(function(){
auth.login('twitter', {
RememberMe: true
});
});
These are the Firebase Rules I'm using
{
"rules": {
".read": true,
"$comment": {
".write": "!data.exists() && newData.child('twitter_id').val() == auth.id"
}
}
}
And this is what happens after press Twitter Log button in my app
Error: FirebaseSimpleLogin: An unknown error occurred
Honesly, I don't know why it happening. Would you give a hand?
I found the solution thanks to #RobDiMarco.
The error was occuring due to an incorrect copy of Twitter API ID and API Secret into my Firebase Forge. I just needed to copy these and then paste it here.
The terminology is very confusing in Firebase Simple Login documentation. Firebase requires three things:
Twitter App ID (used in the client call), which is the "API key" from API keys tab in your Twitter application settings page
Twitter Consumer Key (entered into Firebase Forge), which is also the "API key"
Twitter Consumer Secret (entered into Firebase Forge), which is the "API secret" from the same tab

Categories

Resources