hello guys i developed an android app that http post req some data like latitude, longitude and IMEI to server that post in database. everything is working fine, but now comes the second part of the project. I need to make an web application that shows me on map a market with the lat and long saved in database and i don't understand how. I understood i should use querys but i don't understand who to use them.
this is my server side.
var express = require('express');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var app = express();
//connect to mongodb:
/*mongoose.connect('mongodb+srv://tudorstanciulescu:19970826#test-
srqul.mongodb.net/test?retryWrites=true&w=majority', {useNewUrlParser:
true} );
*/
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/mydb";
//app.use(bodyParser.urlencoded({extended:true}));
//app.use(bodyParser.json());
app.use(bodyParser.json());
//var mongoose = require('mongoose');
app.post('/postBazaDate',(req,res)=> {
var latitudine = req.body.latitudine;
var longitudine = req.body.longitudine;
var imei = req.body.imei;
var dateTime = new Date();
;
var data = {
"latitude" : latitudine,
"longitute" : longitudine,
"imei" : imei,
"dateTime" : dateTime
}
// data.save()
// .then(item => {
// res.send("item saved to database");
// })
// .catch(err => {
// res.status(400).send("unable to save to database");
// });
MongoClient.connect(url, { useNewUrlParser: true }, function(err,
db) {
if (err) throw err;
var dbo = db.db("mydb");
dbo.collection("date_locatie").insertOne(data, function(err, res)
{
if (err) throw err;
console.log("1 document inserted");
});
});
i don't have any errors, everything is working fine, but i can't understand how to use the data from database in a script from an html
In Node.js, same place where you have added app.post
app.get('/getBazaDate',(req,res)=> {
MongoClient.connect(url, { useNewUrlParser: true }, function(err,
db) {
if (err) throw err;
var dbo = db.db("mydb");
dbo.collection("date_locatie").find({}, function(err, data)
{
if (err) throw err;
res.send(data); // here data is containing all saved data in array
//format
});
});
in html file
<!DOCTYPE html>
<html>
<body>
<h2>The = Operator</h2>
<p id="demo"></p>
<script>
const userAction = async () => {
fetch('http://localhost:3000/getBazaDate')
.then(response => response.json())
.then(json => console.log(json))
}
userAction();
document.getElementById("demo").innerHTML = response.json;
</script>
</body>
</html>
Simple REST Explanation
Ok so first is first, an html file is static and its contents can only be manipulated through javascript or css or someother language. Therefore, either you fetch the data before you load the page and send the data with the page , or you create an ajax call to get the data.
In a rest architecture you have GET , PUT , PATCH, POST ,DELETE Requests, each request is to either create ,read , or update the database.
A GET is to send data from server -> client, therefore a client requests data from the server and the server fetches and prepares the data for the client and sends it back.
Both PUT and PATCH updates the data in the database
A POST is to send from client -> server and save data
A DELETE to delete a row from the database
For more information about restfull you can visit this website: https://www.restapitutorial.com/lessons/httpmethods.html
or do a quick google search rest tutorial and you will find many !
Code Time
SERVER SIDE (USE ONE OF THESE) :
// app.js
// THIS GETS ONE ROW AND RETURNS OBJECT FROM THE DATABASE ACCORDING TO YOUR QUERY
app.get("/", (req,res,next) {
dbo.collection("date_locatie").find({}, function(err, res) {
if (err) throw err;
res.send(data);
});
})
// THIS GETS MANY ROWS AND RETURNS ARRAY FROM THE DATABASE ACCORDING TO YOUR QUERY
app.get("/", (req,res,next) {
dbo.collection("date_locatie").findAll({}, function(err, res) {
if (err) throw err;
res.send(data);
});
})
Now that your server is setup to get accept a GET REQUEST AND send back the data
All you have to do is call the url using an ajax call in javascript and your data will be sent to the client's pc.
To show the data you need to loop (if its array) and append data to HTML.
CLIENT SIDE :
In an html file you can write javascript in a script tag. This allows for the DOM elements to be manipulated. Supposed you have an empty with id locationData
and you want to fill it with the data that you saved
//index.html
//Assuming you are using jQuery
<div id="locationData"></div>
<script>
// WHEN HTML IS FULLY LOADED SENDS A GET REQUEST TO YOUR SERVER TO FETCH
// THE DATA
$( document ).ready(function() {
$.ajax({url: "http://localhost:3000/", success: function(result){
// PUTS THE DATA IN THE DIV WITH ID : locationData
$("#locationData").html(result);
}});
});
<script>
Related
I have written an API for client side in node and I want that when a client hits the end-point only a string response is shown to client but as client hits the API an html file should be updated on the client side. Please let me know how to generate separate responses to client and admin from a single API in node.
app.get('/', function(req, res) {
res.sendfile('index.html');//sending file in response to client
});
// something like above is been done which sends response file to the client but i wants that it only updated and shown to the admin at the time of request.
const app = express();
const port = process.env.PORT || 3000;
const server = require('http').createServer(app);
//socket imported
const io = require('socket.io')(server);
//end-point 'ring'
app.post('/ring', (request, response)=>
{
console.log(request.body);
const data=request.body;
if(!data)
{
//if data is not sent then error status
return response.status(400).send('bad request');
}
// here i need to implement explicit responses
console.log((`data is----> ${data}`));
//here i'm emitting my json object to the html file
// this json object should be sent to the html to show
io.emit('message'{'requestbody':request.body,'status':'ringing'});
// sending success response to the client
response.status(200).send('ringing');
});
Index.html code
<body>
<script src=”/socket.io/socket.io.js”></script>
<script
//initializing socket
var socket = io();
//trying to recieve json object from socket
socket.on(‘message’, addMessages)>//calling the addMessage function
</script>
<script>
function addMessages(message)
{
//setting the text extracted from json object
$(“#messages”).append(`
//setting probeId
<h4> ${message.probeId} </h4>
//setting status
<p> ${message.status} </p>`)
}
</script>
//my 'index.html' file should be updated when user hits the ring api and user gets a string response.
I am pretty sure you don't need socket for what you need.
If my understanding of the question is good enough, you can just add a parameter to separate the type of return
app.post('/ring', (request, response)=>
{
console.log(request.body);
const data=request.body;
if(!data)
{
//if data is not sent then error status
return response.status(400).send('bad request');
}
if(data.returnType === 'html'){
response.sendFile(path.join(__dirname + '/index.html'));
} else {
response.status(200).send('ringing');
}
})
returnType is a POST parameter to separate the return types.
update :
if you want to update your index
app.post('/ring', (request, response)=>
{
console.log(request.body);
const data=request.body;
if(!data)
{
//if data is not sent then error status
return response.status(400).send('bad request');
}
if(data.returnType === 'html'){
response.sendFile(path.join(__dirname + '/index.html'));
} if(data.returnType === 'json'){
// Business logic here
let result = { a: 'aez' };
return response.json(result);
} else {
response.status(200).send('ringing');
}
})
And in your html
<body>
<script>
$("#envoyer").click(function(){
$.ajax({
url : 'send_mail.php',
type : 'POST',
data : 'dataType=json'
success: handle
});
});
function handle(result, status)
{
//setting the text extracted from json object
$(“#result”).append(`<div> ${result.a} </div>`)
}
</script>
</body>
I am building an app using ionic/cordova. I need to be able to scan a barcode, then add a timestamp (achieved this) to the devices native storage.
I tried just adding scan data to the native storage, but found that it just overwrites existing scan data. I then tried this using an array, but again noticed if I change page, when the page loads again the array is empty, so that it replaces existing data with the new empty array.
What I "think" I need to do is -
Create an empty array
Take existing data native storage and add to this array
Add new scan data to this array
Then add the array back to native storage.
What I am currently stuck on is taking the data out of native storage and adding to an array.
My code is -
export class ScanSession {
scans: any [];
constructor(private barcodeScanner: BarcodeScanner, private
nativeStorage: NativeStorage) {
this.scans = [];
}
ScanCode() : any{
this.barcodeScanner.scan().then((barcodeData) => {
this.nativeStorage.getItem('scans')
.then(
data => console.log(data),
error => console.error(error)
);
this.scans.push(data);
let inputString = "testData";
//let ts = new Date();
if( barcodeData.text == inputString){
//this.scans.push(ts);
this.nativeStorage.setItem('scans', (JSON.stringify(this.scans)))
//(JSON.stringify(this.scans)
.then(
() => console.log('Stored item!'),
error => console.error('Error storing item', error)
);
//console.log("Success");
//console.log(this.scans);
//this.nativeStorage.getItem('scans')
//.then(
// data => console.log(data),
// error => console.error(error)
// );
} else {
console.log("Doesnt Match");
}
}, (err) => {
});
};
}
Your missing JSON.parse as your using JSON.stringify, you need to unstringify, if you get what i mean.
Change
this.nativeStorage.getItem('scans')
To
JSON.parse(this.nativeStorage.getItem('scans'))
i have an error with the Image Upload from Facebook in my Titanium Software, everytime i want to upload an image from my App i get this:
Fail: REST API is deprecated for versions v2.1 and higher
But if i try the same code in the KitchenSink example app, it works perfect:
var xhr = Titanium.Network.createHTTPClient({
onload: function() {
// first, grab a "handle" to the file where you'll store the downloaded data
var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory,'mygraphic.png');
f.write(this.responseData); // write to the file
var blob = f.read();
var data = {
caption: 'behold, a flower',
picture: blob
};
facebook.request('photos.upload', data, showRequestResult);
},
timeout: 10000
});
xhr.open('GET','http://www.pur-milch.de/files/www/motive/pm_motiv_kaese.jpg');
xhr.send();
And in my App:
function showRequestResult(e) {
var s = '';
if (e.success) {
s = "SUCCESS";
if (e.result) {
s += "; " + e.result;
}
} else {
s = "FAIL";
if (e.error) {
s += "; " + e.error;
}
}
alert(s);
}
Ti.App.hs_stats.addEventListener('touchend', function(e){
Ti.App.hs_stats.top = 255;
var xhr = Titanium.Network.createHTTPClient({
onload: function() {
// first, grab a "handle" to the file where you'll store the downloaded data
var f = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory,'mygraphic.png');
f.write(this.responseData); // write to the file
var blob = f.read();
var data = {
caption: 'behold, a flower',
picture: blob
};
Ti.App.fb.request('photos.upload', data, showRequestResult);
},
timeout: 10000
});
xhr.open('GET','http://www.pur-milch.de/files/www/motive/pm_motiv_kaese.jpg');
xhr.send();
});
Looks like you're using the 'old' Facebook module for Appcelerator? I have image uploads working for Profiles and Pages (although Pages is a bit different, I'll explain later). Here's some quick code (I assume you already authenticated with Facebook):
var fb = require('facebook');
fb.appid = "xxxxxxxxxxxxxxxxx";
var acc = fb.getAccessToken();
fb.requestWithGraphPath('me/photos?access_token='+ acc, {picture:image, message: data}, "POST", showRequestResult);
The image variable is just a blob - It comes directly from event.media from a gallery selection or camera intent. data is the text for your status update.
In your tiapp.xml add these lines:
<property name="ti.facebook.appid">xxxxxxxxxxxxxxxxx</property>
and (if you're using Android and iOS - add both or just the platform you're using)
<modules>
<module platform="android">facebook</module>
<module platform="iphone">facebook</module>
</modules>
Now Pages were a bit strange:
var endPoint = 'https://graph.facebook.com/v2.1/' + pid + '/photos?access_token='+ acc;
xhr.open('POST',endPoint);
xhr.send({
message: data,
picture: image
});
You have to use an HTTP Request, as I couldn't get the requestWithGraphPath() to work with pages no matter what I tried.
pid is your page ID and you can get it, or a list of pages you are an admin for like so (again, create a new HTTP Request (xhr) and use this):
xhr.open("GET","https://graph.facebook.com/v2.1/me?fields=accounts{access_token,global_brand_page_name,id,picture}&access_token=" +fb.getAccessToken());
This will return the access token for each page, the global brand name (basically a clean version of the page name), it's id and the profile picture. The access token in this URL is YOUR personal access token (the &access_token= part).
As far as I can tell, these access tokens don't expire for pages, so you can save it in your app somewhere or if you REALLY want to be safe, you could grab a token before each post, but that's a bit much.
BONUS:
If you want to do video posts to pages:
var xhr = Titanium.Network.createHTTPClient();
var endPoint = 'https://graph-video.facebook.com/'+ pid +'/videos?access_token='+ acc;
xhr.open('POST',endPoint);
xhr.setRequestHeader("enctype", "multipart/form-data");
xhr.send({source:video, description:data});
and for profiles:
var acc = fb.getAccessToken();
var xhr = Titanium.Network.createHTTPClient();
var endPoint = 'https://graph-video.facebook.com/me/videos?access_token='+ acc;
xhr.open('POST',endPoint);
xhr.setRequestHeader("enctype", "multipart/form-data");
xhr.send({source:video, description:data});
video is another blob from either your camera or gallery event.media intent and data is the text you want to use for the status update.
Is it possible to communicate an android Application with cakePhp website and share data? If it is possible, I want to create an application that can login into the website; my doubt is:
How to pass user name and password from our application to cakephp websites login page? Can anybody show me an example program?
How cakephp controller handle this request and respond to this request? Please show me an example program?
(I am a beginner in android and cakephp.)
Quick answer -- YES!
We just finished pushing an Android app to the market place that does this exact thing. Here's how we did it:
1) Download and learn to use Cordova PhoneGap (2.2.0 is the latest version) within Eclipse. This makes the whole thing so much easier with just some HTML and a lot of Javascript.
2) In your JS, create methods that push the login information using AJAX parameters. Example:
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() {
$("#login").click(function() {
$email = $("#UserEmail").val();
$pass = $("#UserPassword").val();
$.ajax({
url : yourURL + 'api/users/login',
async : false,
data : {
'email' : $email,
'password' : $pass
},
dataType : 'json',
type : 'post',
success : function(result) {
/**
* do your login redirects or
* use localStorage to store your data
* on the phone. Keep in mind the limitations of
* per domain localStorage of 5MB
*/
// you are officially "logged in"
window.location.href = "yourUrl.html";
return;
},
error : function(xhr, status, err) {
// do your stuff when the login fails
}
});
}
}
3) In Cake / PHP, your Users controller here will take the username and password data in the AJAX call and use that for its authentication.
<?php
class UsersController extends AppController {
public $name = 'Users';
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('api_login');
}
public function api_login() {
$this->autoRender = false;
if ($this->request->data && isset($this->request->data['email']) && isset($this->request->data['password'])) {
$arrUser = $this->User->find('all',array(
'conditions'=>array(
'email'=> $this->request->data['email'],
'password' => $this->Auth->password($this->request->data['password']),
)
)
);
if (count($arrUser) > 0) {
$this->Session->write('Auth.User',$arrUser[0]['User']);
// Do your login functions
$arrReturn['status'] = 'SUCCESS';
$arrReturn['data'] = array( 'loginSuccess' => 1,'user_id' => $arrUser[0]['User']['id'] );
} else {
$arrReturn['status'] = 'NOTLOGGEDIN';
$arrReturn['data'] = array( 'loginSuccess' => 0 );
}
} else {
$arrReturn['status'] = 'NOTLOGGEDIN';
$arrReturn['data'] = array( 'loginSuccess' => 0 );
}
echo json_encode($arrReturn);
}
}
?>
That's pretty much it. You are now authenticated to CakePHP.
You do not need to use "api_", you can use any function name you want, but this helped us keep a handle on what we allowed mobile users to do versus web users.
Now, these are just the building blocks. You basically have to create a whole version of your site on the phone using HTML and Javascript, so depending on your application it may be easier just to create a responsive design to your site and allow mobile browsing.
HTH!
Use Admad JWT Auth Plugin
If you use cakephp3 change your login function with this one :
public function token() {
$user = $this->Auth->identify();
if (!$user) {
throw new UnauthorizedException('Invalid username (email) or password');
}
$this->set([
'success' => true,
'data' => [
'token' => JWT::encode([
'sub' => $user['id'],
'exp' => time() + 604800
],
Security::salt())
],
'_serialize' => ['success', 'data']
]);
}
You can read this tutorial about REST Api and JWT Auth Implementation
http://www.bravo-kernel.com/2015/04/how-to-add-jwt-authentication-to-a-cakephp-3-rest-api/
if rebuild most of the view pages in cakephp into ajax will seem defeat the purposes of using cakephp as it is.
I'm trying to find the best way to send my users a real-time status update of a process that's running on my server - this process is broken up into five parts. Right now I'm just 'pulling' the status using an Ajax call every few seconds to a PHP file that connects to MySQL and reads the status, but as you can imagine, this is extremely hard on my database and doesn't work so well with users that don't have a strong internet connection.
So I'm looking for a solution that will 'push' data to my client. I have APE push-engine running on my server now, but I'm guessing Socket.IO is better for this? What if they're on 3G and they miss a status update?
Thanks in advance :)
I guess my answer may match what you need.
1st: You Have to Get Node.js to run the socket.io
BELOW IS SAMPLE CODE FOR SERVER:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(8800); //<---------Port Number
//If No Connection / Page Error
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
//If there is connection
io.sockets.on('connection', function (socket) {
//Set Varible
var UserID;
var Old_FieldContent = "";
socket.on('userid', function (data) {
if(data.id){
UserID = data.id;
StartGetting_FileName(UserID)
}
});
//Checking New Status
function StartGetting_FileName(UserID){
//Create Interval for continues checking from MYSQL database
var myInterval = setInterval(function() {
//clearInterval(myInterval);
//MySQL Connection
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
port : '3306',
user : 'root',
password : 'ABCD1234',
database : 'test',
});
//Setup SQL Query
var SQL_Query = "SELECT FileName FROM status WHERE UserID = '"+UserID+"'";
connection.connect();
connection.query(SQL_Query, function(err, rows, fields) {
//Do if old result is, different with new result.
if(Old_FieldContent !== rows[0].FileName){
if (err) throw err;
//Display at Server Console
console.log('------------------------------------------');
console.log('');
console.log('Fields: ', fields[0].name);
console.log('Result: ', rows[0].FileName);
console.log('');
console.log('------------------------------------------');
//Send Data To Client
socket.emit('news', { FieldName: fields[0].name });
socket.emit('news', { FieldContent: rows[0].FileName });
//Reset Old Data Variable
Old_FieldContent = rows[0].FileName;
}
});
connection.end();
}, 500 );
}
});
BELOW IS CLIENT HTML & JS:
<!doctype html>
<html>
<head>
<title>web sockets</title>
<meta charset="utf-8">
<!-- URL PATH TO LOAD socket.io script -->
<script src="http://15.17.100.165:8800/socket.io/socket.io.js"></script>
<script>
//Set Variable
var UserID = "U00001";
var socket = io.connect('http://15.17.100.165:8800');
var Field_Name = "No Data";
var Field_Content = "No Data";
// Add a disconnect listener
socket.on('connecting',function() {
msgArea.innerHTML ='Connecting to client...';
console.log('Connecting to client...');
//Once Connected Send UserID to server
//for checking data inside MYSQL
socket.emit('userid', { id: UserID });
});
// Get data that push from server
socket.on('news', function (data) {
console.log(data);
writeMessage(data);
});
// Add a disconnect listener
socket.on('disconnect',function() {
msgArea.innerHTML ='The client has disconnected!';
console.log('The client has disconnected!');
});
//Function to display message on webpage
function writeMessage(msg) {
var msgArea = document.getElementById("msgArea");
if (typeof msg == "object") {
// msgArea.innerHTML = msg.hello;
if(msg.FieldName !== undefined){
Field_Name = msg.FieldName;
}
if(msg.FieldContent !== undefined){
Field_Content = msg.FieldContent;
}
}else {
msgArea.innerHTML = msg;
}
msgArea.innerHTML = Field_Name +" = "+ Field_Content;
}
</script>
</head>
<body>
<div id="msgArea">
</div>
</body>
</html>
You should consider using push notifications, with the service provided for Android by Google as C2DM: https://developers.google.com/android/c2dm/
You will need to implement a PhoneGap plugin to handle the native notifications, and communicate them to your PhoneGap project that will then (and only then) query your server .
As K-ballo above points out, using a push notification plugin would be best.
Luckily, some good citizen on GitHub has done this already!
https://github.com/awysocki/C2DM-PhoneGap
Please note: the above C2DM plugin was built for PhoneGap v1.2, so if you are running a more up-to-date version you will have to tweak the native code a bit to get it working better.