How should the structure be built for Firebase Requests - android

Brief information: I am working on a quiz application for Android. The database is on Firebase and the users login via anonymously. When the user opened the application, it will be automatically signed-in.
My question is about firebase. I could not build the intelligence for firebase requests.
When the application is opened;
1) signInAnonymously (which firebase function) should be called first.
2) Then i check that the signed user has a saved point or not on firebase database.
3) If the user does not have point, it is generated.
4) Then i send a request to get the point of user.
In all steps, i send a request to firebase via async firebase methods. The sequence is important because the output of any step can be an input for the next step.
I handle this via callback. But i do not know that it is the best way.
screenshots of callbacks for these steps
Can you give me advice for these? If i do not use callbacks, problems are occured because of asynchronous firebase methods. The reason of that i open this issue is undetermined problems. I can learn and build any other algorithm to make it better. Thank you.

It looks like you are using nested callbacks and I am not a Java programmer, but you may want to take it easy on yourself and not go that route.
If my signing in anonymously you mean a One-Time-Password authentication flow such as just providing a phone number, that would definitely be a good approach.
You can use Google Cloud Functions, but the functions would have to be written in Nodejs, Python or Go.
Either way take a look at this flow below:
User requests OTP
Acknowledge the request
Generate code, save the code on backend (GCF)
Text user the code
User sends you the correct code
Compare codes on the server
Send user some kind of token or as you say a "point" to identify them.
I do believe Java does have support for JSON Web Tokens.
So after your setup GCF project, you are going to get some folder and files like so:
.firebaserc: a hidden file that helps you quickly switch between projects with firebase use.
firebase.json: describes properties for your project.
functions/: this folder contains all the code for your functions.
functions/package.json: an NPM package file describing your Cloud Functions.
functions/index.js: the main source for your Cloud Functions code.
functions/node_modules/: the folder where all your NPM dependencies are installed.
You want to import the needed modules and initialize the app:
const admin = require("firebase-admin");
const functions = require("firebase-functions");
const serviceAccount = require("./service_account.json");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://my-project.firebaseio.com"
});
That service_account.json is something you need to create, its not a library.
It will have a bunch of private and public keys that you get from your Firebase console. Ensure you also place that file inside your .gitignore files as well.
So I am skipping some crucial details here that you will have to figure out so as to get to your main question.
First, you need the idea of a user, so you need to create a user inside GCF so that in itself is going to be a function and as you mentioned Firebase is asynchronous so it would look something like this:
const admin = require("firebase-admin");
module.exports = function(req, res) {
// Verify the user provided a phone
if (!req.body.phone) {
return res.status(422).send({ error: "Bad Input" });
}
// Format the phone number to remove dashes and parens
const phone = String(req.body.phone).replace(/[^\d]/g, "");
// Create a new user account using that phone number
admin
.auth()
.createUser({ uid: phone })
.then(user => res.send(user))
.catch(err => res.status(422).send({ error: err }));
// Respond to user request saying account was made
};
So the code above I grabbed from a previous project of mine, except the whole thing was in JavaScript. For you this part will be in JavaScript or Nodejs specifically as well since again, Nodejs, Go or Python are the only languages supported by GCF.
So the comments are self-explanatory but I feel compelled to explain that the first thing I had to resolve is how to pass in information to this function in a request.
To do that I had to reference the req.body object as you see above. req.body contains all the different data that was passed to this function when the user called it. I was not sure if you knew that. So before you go and copy paste what I have above, do a res.send(req.body);. So nothing else inside that module.exports = function(req, res) {} except res.send(req.body);, so you can get a good sense of how this all works.
For every function you create you need to run a firebase deploy name-of-project.
After you feel you have a handle on this and its all working successfully, you can create your Android Studio project and add the database dependency like so:
compile 'com.google.firebase:firebase-database:10.2.1'
And then you will probably want to create your User model, maybe like this:
public class User {
public String phone;
public User() {
// Default constructor required for calls to DataSnapshot.getValue(User.class)
}
public User(String phone) {
this.phone = phone;
}
}
And so on, anyway I hope that kind of gives you a good enough idea that it gets you going. Best of luck. I know I failed to take time out to explain that the regex in my code is to sanitize the phone number and probably some other stuff. So again, don't just copy paste what I offered, study it.

Related

Can I use SafetyNet with firebase functions?

I am trying to implement SafetyNet in my app. I also, don't have a server, and I am using Firebase Firestore and Firebase Functions.
My knowledge about Firebase Functions is very limited. And I was wondering if I could somehow use the functions to help me with the SafetyNet attestation. As I see, I should be producing a nonce on the cloud, send this nonce to the app, use it to attest, and send it back to the cloud to verify the integrity correct?
But I can't seem to find anywhere on how to do this. Can anyone point me in the right direction?
YES
Sorry for the excitement there, but this is possible since a few weeks ago through a new feature called Firebase App Check.
With App Check, you always end up with a two-step process:
Use an attestation provider (such as SafetyNet) in your application, so that information about the app is attached to each request it makes to Firebase.
Then at some point in time, when enough of your app requests have this information attached, check for the app information in Cloud Functions, or enable the check in one of the other supported services.
If you check the documentation on enabling App Check enforcement for Cloud Functions, you'll see that it mostly boils down to this check in the code:
exports.yourCallableFunction = functions.https.onCall((data, context) => {
// context.app will be undefined if the request doesn't include a valid
// App Check token.
if (context.app == undefined) {
throw new functions.https.HttpsError(
'failed-precondition',
'The function must be called from an App Check verified app.')
}
// Your function logic follows.
});

Validating password in my application from Yii2 website

Me and my friend are working on final project. My friend is a little bit ahead and made all his database on Yii2 framework.
Everything worked fine, our database is on AWS and I got it by simple requests on my Android app.
Now I came to the part where I need to use login-password. Here I'm stuck, because all I can fetch from database is salted password. My friend used salt on the password part (which is the right thing to do).
The website is still on our hard drive.
1) Do we have to upload it online and only afterward to develop some
API function that calls to database, so my app can access validation
part of the website?
2) Maybe Yii2 already has a validation function
build-in somewhere that can be used by Android app? An example would
be super-helpful.
3) I saw a lot of examples about API functions,
but all of them look pretty complicated and not related to Java at
all.
Yii2 validation is actually online here: https://github.com/yiisoft/yii2-framework/blob/master/base/Security.php on validatePassword function.
Do you implement IdentityInterface on your user model?
if yes, than you can use this in your yii2 rest api.
public function actionLoginUser(){
$data = Yii::$app->request->post();
$username = $data['username'];
$password = $data['password'];
$user = User::findByUsername($username);
if($user->validatePassword($password)){
//your next response
}
}
Where validatePassword method is like this:
public function validatePassword($password)
{
return Yii::$app->security->validatePassword($password, $this->password_hash);
}
Sorry for bad english

call a Google Spreadsheets Apps Script function from Google Sheets API v4

I have a Spreadsheet with some Apps Script functions bound to it.
I also have an Android client using Google Sheets API v4 to interact with that spreadsheet.
Is there a way for the Android client to call/run some function in the Apps Script code?
The reason I need to code to be run on the Apps Script side, and not simply on the Android client, is because I'm sending some email when something happens to the doc, and I would like the email to be sent from the owner account of the spreadsheet, and not from the Android user authenticated via the API.
I know I can trigger functions implicitly like by adding rows to a doc, but is there a way to directly run a specific function?
Yes. You can make GET and POST requests to Google apps-scripts. from anywhere that can make REST type calls including clients. If you need authentication there is also the apps-script client libraries. I wrote a short script for emailing from a request from one apps-script to another here. But, it would work if you called the emailing script from your client also.
Deploy your Google Apps Script as Web Apps > reference, by this way you can run function Get(e) or Post(e) and invoke other functions inside one of them with conditions....
You might have gotten the answer to your question. Just in case you have not, below are some points that may help with your development:
1) Create the server side script (i.e., Google Apps Script) function like usual:
function myFunction(inputVar) {
// do something
return returnVar;
}
2) Create a doGet(e) or doPost(e) function like below - can be in the same .gs file with the function in 1) :
function doGet(e) {
var returnVar = "";
if (e.parameter.par1 != null) {
var inputVar = e.parameter.par1;
returnVar = myFunction(inputVar);
}
return HtmlService.createHtmlOutput(returnVar);
}
3) Publish and deploy your project as webapp. Note the deployed URL.
4) From your Android client do HTTP call with the URL as: your_webapp_url?par1="input value"

how to get user information in google wallet

We want to be able to associate app users with real transactions done.The problem is that we have the user’s email address on application back end side, and we track user purchase amounts, but when we go into the Google Wallet transactions we have no way of knowing which transaction/s belong to that user. We need a solution for this, because even if we have the user's email, we cannot search transactions by email address.
Is it possible to update the receipt numbers we are sending in the API to include the Google Wallet Receipt number instead of the time stamp ?
Please, provide us your suggestions.
I thought the answer would lie in the postback facility. That gives google's user ID and order number. However, I didn't see how to convert either of those to an email address for sending the digital good just purchased.
BTW. I rejected doing the fulfilment client side as that seemed insecure. If I'm wrong about that then why would they offer the postback facility?
... then I realised, we could do part of it client and part server side.
I guessed that something comes back from the client-side success callback.
success: function(result) {
console.log('success',result.response.orderId);
complete(result.response.orderId);
},
So, I now have the google's orderId on the client side and there I know the user's ID. So my complete() function can send the orderId and our userId to the server which can then match this with successful payment orderId from the postback (which happens first) and fulfil the order.
Yes, this is inelegant, but I believe it to be a secure solution.
Maybe slightly more elegant is to use the [sellerData] property in the submission payload to contain our user ID and order ref. We then have more items to match after the success callback has happened. I think I'll hold off delivering the digital good until all those checks have been completed.
What I do not understand is why cannot this kind of suggestion (or a better one) be found in the wallet tutorial?
Paul
My answer here refers to the previous answer provided:
Totally agree on "why cannot this kind of suggestion (or a better one) be found in the wallet tutorial?".
Your suggested solution does not seem to be very secured (to say the least). You want the client to send you their username/email/client-id in the Success callback... This means that anyone will be able to send you their ID, even if they did not make a purchase. They can add a random order-ID and hope to get a match (and then repeat the process many times in order to increase the chances).
My guess is that the username/email/client-id lies somewhere in the request object sent from Google to the postback URL (your server's doPost routine). But I have the feeling that you need to add something in the JWT generated in your Purchase function before it is passed to the google.payments.inapp.buy routine.
Looking for an answer myself...
Here is a possible solution, although I have not yet tested it myself:
Download the 'zip' file from: https://code.google.com/p/wallet-online-quickstart-java/downloads/list
Take the entire 'com' folder and add it to your project source folder (sorry, I have not been able to find a JAR for this package). Then, add the following code to your servlet:
...
import com.google.wallet.online.jwt.JwtResponseContainer;
import com.google.wallet.online.jwt.util.JwtGenerator;
import com.google.wallet.online.jwt.JwtResponse;
...
public void doPost(HttpServletRequest request, HttpServletResponse response) ...
{
try
{
String maskedWalletJwt = request.getParameter("maskedWalletJwt");
JwtResponseContainer jwtResponseContainer = JwtGenerator.jwtToJava(JwtResponseContainer.class, maskedWalletJwt, SellerSecret);
JwtResponse jwtResponse = jwtResponseContainer.getResponse();
String email = jwtResponse.getEmail();
...
}
}
One thing I'm not so sure about, is request.getParameter("maskedWalletJwt").
You might have to add this parameter when calling the google.payments.inapp.buy routine.

Cakephp and custom authentification for mobile application

Hey i'm working on a web application in combination with an android app. Now i want in my mobile app that the user have to log in with the same user data like on the web application. So i want to send a username and a password to the controller and in the login action of this controller the user should be verified and the additional user id should be send back to the application (the id is used for several operations in the app). I looked for the Auth Component of CakePHP but i don't find any solution for my problem. I hope you can help me.
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('index','view');
$this->set('logged_in', $this->Auth->loggedIn());
$this->set('current_user',$this->Auth->user());
if($this->name == 'Specific') {
// for the specific controller
$this->Auth->authenticate = array('Basic');
} else {
// everything else
}
}
checkout KVZ's rest plugin it may be of interest https://github.com/kvz/cakephp-rest-plugin
Not sure about what you need to do on the cakephp side of things, but if you want to have a set of account credentials stored securely and persistently on an Android device, I suggest you take a look at the AbstractAccountAuthenticator class.
The AuthComponent has a login() method you can use to manually login users. Depending on the Cake version you're using this method also checks the credentials you supply (actually Auth is completely restructured in 2.0 in a way that's much more useful for situations like yours, it's worth taking a look!).
You can send in the login credentials from your android app any way you please (XML, POST parameters), extract them in your login action and send them to the AuthComponent (or, in 2.0, write a custom authenticator object to handle it all).

Categories

Resources