How do we store facebook user's details in parse? - android

I am using login with facebook utility of parse in my android application. Login with facebook utility works fine. it inserts only "userName" and "authData" column of "User" table.
I am getting name and email of facebook user using graph API of facebook.
Question -
How do we store "fullName" and "email" of facebook user into parse?
Thanks in advance!

I was able to write user Facebook details in CloudCode by doing the following:
Parse.Cloud.beforeSave(Parse.User, function (request, response) {
// Use Master Key
Parse.Cloud.useMasterKey();
// Pull User Object
var User = request.object;
// User Check
if (!User) {
// Not allowed
response.error();
return;
}
// For some reason, pulling authData fails. A try catch helps the TypeError that may happen
try {
var authData = User.get('authData');
var access_token = authData.facebook.access_token;
} catch(e) {
var access_token = null;
}
Parse.Cloud.httpRequest({
url:'https://graph.facebook.com/v2.1/me?fields=picture.height(50).width(50),email,first_name,last_name,friends.limit(5000),name,gender&access_token='+access_token,
success:function (httpResponse) {
// Success
var facebookIds = [];
try {
var facebookFriends = httpResponse.data.friends.data;
} catch (e) {
var facebookFriends = [];
}
var promise = _.each(facebookFriends, function(facebookFriend) {
facebookIds.push(facebookFriend.id);
});
Parse.Promise.when([promise]).then(function () {
if (request.object.existed() == false) {
User.set("displayName", httpResponse.data.name);
}
// Updating user object
User.set("facebookFriends", facebookIds);
User.set("fbEmail", httpResponse.data.email);
User.set("profileThumb", httpResponse.data.picture.data.url);
User.set("facebookId", httpResponse.data.id);
User.set("gender", httpResponse.data.gender);
response.success();
});
},
error:function (error){
// Error
response.error('Server error.')
}
});
});

Related

How do I get Flutter to check if a value in a child node for Firebase Realtime Database matches user input (Android)?

I'm completely new to flutter development and I am making a login for admins in my flutter mobile app.
The email address used in the login already exists in Firebase Authentication, but before I have it proceed to logging in the app, I first need to check if the inputted email address is stored in Realtime Database. How do I go about this in terms of code?
The flow is like this: user inputted "abc#gmail.com" as email address for login. App checks rtdb if there is a value of "abc#gmail.com", if true, proceed with login.
I understand I have to use
var rtdbref =
FirebaseDatabase.instance.reference().child("Admins").child("adminEmail");
but after that I have no idea how to have Flutter read the values. Any help is very much appreciated! Thank you :)
Image for rtdb reference:
screenshot of rtdb
Code I have so far:
final FirebaseAuth _firebaseAuth = FirebaseAuth.instance;
var rtdbref =
FirebaseDatabase.instance.reference().child("Admins").child("adminEmail");
void loginAdmin(BuildContext context) async {
try {
final User? firebaseUser =
(await _firebaseAuth.signInWithEmailAndPassword(
email: emailTextEditingController.text,
password: passwordTextEditingController.text))
.user;
if (firebaseUser != null) {
var isAdmin = await rtdbref.child("Admins").once();
if (isAdmin.value["adminEmail"] == emailTextEditingController.text) {
//check if admin here
if (firebaseUser.emailVerified) {
//if (firebaseUser.emailVerified) {
usersRef.child(firebaseUser.uid).once().then((DataSnapshot snap) {
if (snap.value != null) {
Navigator.pushNamedAndRemoveUntil(
context, Navbar.idScreen, (route) => false);
//displayToastMessage("Homepage", context);
}
});
} else {
displayToastMessage("Please verify your account", context);
await firebaseUser.sendEmailVerification();
}
} else {
_firebaseAuth.signOut();
displayToastMessage("Account does not exist", context);
}
}
} on FirebaseAuthException catch (e) {
if (e.code == 'wrong-password') {
displayToastMessage("Wrong password", context);
}
if (e.code == 'too-many-requests') {
displayToastMessage("Please try again after 2 minutes", context);
}
if (e.code == 'user-not-found') {
displayToastMessage("User not found", context);
}
}
//displayToastMessage("Admin login test", context);
}
Update: I've attempted the following but still cannot seem to get it to read the adminEmail values of node Admins. What am I missing here? I feel like im so close
DatabaseReference adminsRef =
FirebaseDatabase.instance.reference().child("Admins");
var isAdmin = adminsRef
.orderByChild("adminEmail")
.equalTo(emailTextEditingController.text);

How to login with linkedin in an application where mobile and nodejs are used together

I can not create a server session in the mobile requests.
I am developing a mobile application. Sign in with LinkedIn to application made only from mobile.
I wrote the rest api with nodejs. I used the passport for linkedin login.Then I tested it from browser.It worked smoothly on browser.
When i make a request to my endpoint(/auth/linkedin) it redirect to linkedin and typing my account information and allow the app .It is redirect again to callback endpoint (auth/linkedin/callback). I am returning information of the logged-in user if success login. I am making process this session information on next requests.
But when I login from mobile, user information is printed webview and I cannot create session.How can i solve this problem. What am I doing wrong?
I am junior. if you see my code wrong please specify for improve my skill.
app.js
const AuthController = require("./router/Auth");
app.use(express.json());
app.use(session({
secret:'secretkey',
saveUninitialized: false,
resave: true,
cookie: {maxAge: 365*24*60*60*1000}
}));
app.use(passport.initialize());
app.use(passport.session());
app.use('/auth',AuthController);
passport.use(new LinkedInStrategy({
clientID: config.linkedin.clientID,
clientSecret: config.linkedin.clientSecret,
callbackURL: config.baseUrl[env] + "/auth/linkedin/callback",
scope: config.linkedin.scope
},
function(accessToken, refreshToken, profile, done) {
User.findOne({'linkedin.id' : profile.id}, function(err, user) {
if (err) return done(err);
if (user) return done(null, user);
else {
// if there is no user found with that linkedin id, create them
var newUser = new User();
// set all of the linkedin information in our user model
newUser.linkedin.id = profile.id;
newUser.linkedin.token = accessToken;
newUser.name = profile.displayName;
if (typeof profile.emails != 'undefined' && profile.emails.length > 0)
newUser.email = profile.emails[0].value;
if(typeof profile.photos != 'undefined' && profile.photos.length> 0)
newUser.photo = profile.photos[0]
// save our user to the database
newUser.save()
.then(createWallet)
.then(updateWallet)
.then(user => {
return done(null,user)
})
.catch(err =>{
throw err;
});
}
});
}
));
passport.serializeUser(function(user, done){
done(null, user.id)
})
passport.deserializeUser(function(id, done) {
User.getUserById(id, function(err, user) {
done(err, user);
});
});
app.listen(PORT,()=>{
console.log("Listening...",PORT);
});
function createWallet (user){
const userId = user.id;
return new Promise((resolve,reject) => {
request(config.blockChain['url']+'/?type=register&userID='+userId,{json:true} ,(err,res,body)=>{
if(err) reject(err);
user.wallet = {
"secret":body.secret,
"publicKey":body.publicKey
}
resolve(user);
})
}
)
}
function updateWallet(user){
return user.save();
}
Auth.js
router.get('/linkedin', passport.authenticate('linkedin'));
router.get('/linkedin/callback',
passport.authenticate('linkedin',{ failureRedirect: '/'}),(req,res)=>{
const user = req.user;
response = {
status:true,
msg:"Login is successfull",
data: user
}
res.status(200).json(response);
});

Authentication with Passport Session on Android

I have a web app currently running with NodeJS and Express, where I authenticate the users using Passport sessions, and it works perfectly. Here is the overview of what I do:
app.use(session({
secret : 'hidden of course :)',
resave: false,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
/****** Passport functions ******/
passport.serializeUser(function (user, done) {
done(null, user.idUser);
});
passport.deserializeUser(function (id, done) {
db.user.findOne( { where : { idUser : id } }).then(function (user, err) {
done(null, user);
});
});
//Facebook
passport.use(new FacebookStrategy({
//Information stored on config/auth.js
clientID: *******,
clientSecret: ******,
callbackURL: *******,
profileFields: ['id', 'emails', 'displayName', 'name', 'gender', 'picture.type(large)']
}, function (accessToken, refreshToken, profile, done) {
//Using next tick to take advantage of async properties
process.nextTick(function () {
db.user.findOne( { where : { idUser : profile.id } }).then(function (user, err) {
if(err) {
return done(err);
}
if(user) {
return done(null, user);
} else {
// Check whether the email is undefined or valid
var emailTemp = '';
if(profile.emails && profile.emails[0] && profile.emails[0].value) {
emailTemp = profile.emails[0].value;
} else {
emailTemp = '';
}
var picture = '';
if(profile.photos && profile.photos[0] && profile.photos[0].value) {
picture = profile.photos[0].value;
} else {
picture = '/img/profile.png';
}
var sexFb = '';
if(profile.gender) {
sexFb = profile.gender;
} else {
sexFb = '';
}
// Create the user
db.user.create({
idUser : profile.id,
token : accessToken,
picture : picture,
nameUser : profile.displayName,
email : emailTemp,
sex : sexFb
}).then(function () {
db.user.findOne( { where : { idUser : profile.id } }).then(function (user, err) {
if(user) {
return done(null, user);
} else {
return done(err);
}
});
});
}
});
});
}));
app.use(express.static(__dirname + '/public/'));
/* FACEBOOK STRATEGY */
// Redirect the user to Facebook for authentication. When complete,
// Facebook will redirect the user back to the application at
// /auth/facebook/callback//
app.get('/auth/facebook', passport.authenticate('facebook', { scope : ['email']}));
/* FACEBOOK STRATEGY */
// Facebook will redirect the user to this URL after approval. Finish the
// authentication process by attempting to obtain an access token. If
// access was granted, the user will be logged in. Otherwise,
// authentication has failed.
app.get('/auth/facebook/callback',
passport.authenticate('facebook', { failureRedirect: '/' }),
function (req, res) {
// Successful authentication, redirect home.
res.redirect('../../app.html');
});
Now, I'm building our Android App and I need to authenticate our users, preferably using the backend I already built for the web version. I was checking some questions on SO like this one and I understood a lot of what I would have to do.
Currently my clients stay logged in through the cookie that Express-session handles, saving the user's id on the req.user, so that I can run queries like on this example:
app.put('/profile', function (req, res) {
//Updates the profile information of the user
db.user.update({
nameUser : req.body.nameUser
}, {
where : {
idUser : req.user.idUser
}
}).then(function (user) {
res.json({ yes : "yes" });
});
});
So my questions:
Can I authenticate my users using the same strategy as the one I currently have? If not, what would I have to change to be able to authenticate my users on Android?
Once they are authenticated, how can I set the req.user from Android (through HTTP request or whatever mean) to correctly perform the tasks on the backend (since all my requests are based on req.user)? I assume Android doesn't keep cookies like browsers do, so how would Passport Sessions know which user is calling the API?
I currently use Retrofit2 on my Android app to interact with the API, is it able to perform the actions necessary for this task?
Sorry for the long post, added a good chunk of code just to be on the safe side, if you guys have any questions or need any explanation please let me know!

com.parse.ParseException: function not found in ParseCloud

so this is the main.js file in my cloud:
Parse.Cloud.define("addChannelToUser",function(request,response)){
var userId = request.params.userId;
var listId = request.params.listId;
var User = Parse.Object.extend("User"),
user = new User({ objectId: userId });
user.add("channels",listId);
Parse.Cloud.useMasterKey();
user.save().then(function(user) {
response.success(user);
}, function(error) {
response.error(error)
});
});
and this is where I call it from my app:
ParseCloud.callFunctionInBackground("addChannelToUser",params,
new FunctionCallback<Object>() {
#Override
public void done(Object o, ParseException e) {
if(e != null){
Log.d("cloud error", e.toString());
}else{
Log.d("cloud", "success");
}
}
});
my goal is to add the lisId to the "channel" field of a user with userId.
of course this user is not the user logged in the device so I obviously need to use the master key...
anyway, I keep getting the error "function not found", please help me :)
I just copy your code to my main.js file and try to deploy the code to Parse Cloud. However, Parse generates me a syntax error where I correct as follows;
Parse.Cloud.define("addChannelToUser",function(request,response)
{
var userId = request.params.userId;
var listId = request.params.listId;
var User = Parse.Object.extend("User"),
user = new User({ objectId: userId });
user.add("channels",listId);
Parse.Cloud.useMasterKey();
user.save().then(function(user) {
response.success(user);
}, function(error) {
response.error(error)
});
});
You can extract where you make mistake. The cloud function is tested in Parse environment. It is working. Hope this helps.
Regards.

Login to facebook with android, phonegap, childBrowser

I managed to log into Facebook with childBrowser plugin without any problems:
function deviceStart() {
FB.init({ appId: "xxxxxxxxxxxxxx", nativeInterface: PG.FB });
};
function onPubFacebookBtn(){ // I call this from a button
var my_client_id = "xxxxxxxxxxxxx",
my_redirect_uri = "http://www.facebook.com/connect/login_success.html",
my_type = "user_agent",
my_display = "touch"
var authorize_url = "https://graph.facebook.com/oauth/authorize?";
authorize_url += "client_id="+my_client_id;
authorize_url += "&redirect_uri="+my_redirect_uri;
authorize_url += "&display="+my_display;
authorize_url += "&scope=publish_stream,user_photos,email,user_online_presence,offline_access"
window.plugins.childBrowser.onLocationChange = facebookLocChanged;
window.plugins.childBrowser.onClose = closed;
window.plugins.childBrowser.showWebPage(authorize_url);
}
function facebookLocChanged(loc){
if (/login_success/.test(loc)) {
var fbCode = loc.match(/code=(.*)$/)[1]
localStorage.setItem('pg_fb_session', JSON.stringify(fbCode));
FB.Auth.setSession(fbCode, 'connected');
window.plugins.childBrowser.close();
}}
When I test if the app is logged in with
function getLoginStatus() {
FB.getLoginStatus(function(response) {
if (response.session) {
alert('logged in');
} else {
alert('not logged in');
}
});
}
it returns "loged in", but when I try to get user ID i get an error saying I need an active access token:
function me() {
FB.api('/me', function(response) {
if (response.error) {
alert(JSON.stringify(response.error));
} else {
var data = document.getElementById('data');
response.data.forEach(function(item) {
var d = document.createElement('div');
d.innerHTML = item.name;
data.appendChild(d);
});
}
});
}
This is a mixture of 2 solutions for loging into facebook of which none works.
Help!?
I have used the following code to get the Facebook user's name, please try once.
params='access_token='+accessToken;
$.get("https://graph.facebook.com/me",params,
function(response){
fbUesrName=response.name;
},"json");
You need to have an application on Facebook to generate access token, then you can get the ID, but it would be in the encrypted form.

Categories

Resources