The situation is as following:
I send a login request using the method showLoginUI and then, after selecting a provider (Twitter, g+, etc.) the app goes to the onError callback of my GSLoginUIListener with the error "Account pending registration". Until that point, everything is fine. The problem is when I try to create another GSRequest with the method "accounts.setAccountInfo" like in the following code:
GSRequest setAccountInfoRequest = new GSRequest(getString(R.string.gigya_api_key),"accounts.setAccountInfo");
As parameter, I believe I have to add the regToken but where can I get it? In the iOS SDK, there is an Error object (that you get from the GSResponse that allows you to get it like this:
token = error.userInfo["regToken"]
But there is nothing like that on the Android SDK, from the GSResponse I just can get the error code, error message and error details. So, in short, how can I get the regToken that I need for my request? In the documentation does not go into the details of the actual implementation and I have not seen any examples.
Unlike the iOS and .NET SDKs, the Android SDK does not have a publicly expose or documented GSRequest class, so invoking a request the way you are doing it is not advisable.
Instead, you should use GSAPI.sendRequest with a GSResponseListener. The GSResponseListener will have a response object with the method getData which can be invoked to get a dictionary object of all the parameters returned from the request.
An example of how this can be done is provided in our Gigya CS Android demo hosted on GitHub and can be examined in the file SessionInfoFragment.java#121-191.
public void refreshView() {
GSAPI gigya = GSAPI.getInstance();
final TextView statusText = (TextView) rootView.findViewById(R.id.status_value);
final TextView nameText = (TextView) rootView.findViewById(R.id.name_value);
final TextView emailText = (TextView) rootView.findViewById(R.id.email_value);
final ImageView avatarView = (ImageView) rootView.findViewById(R.id.avatar);
if (gigya.getSession() != null){
if (gigya.getSession().isValid()) {
MainActivity parent = (MainActivity) getActivity();
GSObject user = parent.getUser();
// Retrieve the user if it's not set. (Reloaded app with active session)
if (user == null) {
GSResponseListener resListener = new GSResponseListener() {
#Override
public void onGSResponse(String method, GSResponse response, Object context) {
try {
if (response.getErrorCode()==0) { // SUCCESS! response status = OK
MainActivity parent = (MainActivity) getActivity();
Log.w("Gigya-Android-Demos", "Successfully set user");
parent.setUser(response.getData());
setLoggedIn(statusText, nameText, emailText, avatarView, response.getData());
} else { // Error
Log.w("Gigya-Android-Demos", "GSResponse: 'getAccountInfo' returned an error");
Log.w("Gigya-Android-Demos", response.getErrorMessage());
}
} catch (Exception ex) { ex.printStackTrace(); }
}
};
GSAPI.getInstance()
.sendRequest("accounts.getAccountInfo", null, resListener, null );
} else {
// Grab the user data
setLoggedIn(statusText, nameText, emailText, avatarView, user);
}
} else {
setLoggedOut(statusText, nameText, emailText, avatarView);
}
} else {
setLoggedOut(statusText, nameText, emailText, avatarView);
}
}
public void setLoggedOut(TextView status, TextView name, TextView email, ImageView avatar) {
status.setText(getString(R.string.logged_out));
name.setText(getString(R.string.null_value));
email.setText(getString(R.string.null_value));
setUnknownAvatar(avatar);
}
public void setLoggedIn(TextView status, TextView name, TextView emailView, ImageView avatar, GSObject user) {
status.setText(getString(R.string.logged_in));
try {
GSObject profile = user.getObject("profile");
String first = profile.getString("firstName");
String last = profile.getString("lastName");
String email = profile.getString("email");
if (profile.containsKey("photoURL")) {
setAvatar(avatar,profile.getString("photoURL"));
} else {
setUnknownAvatar(avatar);
}
name.setText(first + " " + last);
emailView.setText(email);
} catch (Exception ex) {
Log.w("Gigya-Android-Demos", "Something went horribly wrong with the user!");
ex.printStackTrace();
}
}
You should notice the use of getData() and GSObject classes throughout the example provided. Using this method of making a request, you should be able to examine the response data including the regToken.
Related
I made another post to explain better, ok? :)
This video shows exactly what I mean:
The video is: https://www.youtube.com/watch?v=DCg00fe-_xs
Firebase normally stores data. After the 6th second of the video, trying to enter new data, the data stays about a second in Firebase, but automatically then it disappears.
I try to input the data into Firebase two more times in this video, but the data always automatically disappears afterwards.
You can see that the other datas that are stored in Firebase does NOT disappear. But the data of this code is automatically disappearing for some reason as shown in the video. Please what can I do to fix it?
Code:
button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String raça = spinner_raca.getSelectedItem().toString();
final String regiaoDoEstado = spinner_regiaoDoEstado.getSelectedItem().toString();
final String estado = spinner_estado.getSelectedItem().toString();
Intent receiverIntent = getIntent();
Bundle bundleRecebedor = receiverIntent.getExtras();
String nomecompleto = bundleRecebedor.getString("nomecompleto");
String email = bundleRecebedor.getString("email");
String doencasPreExistentes = bundleRecebedor.getString("doencasPreExistentes");
String dataDeNascimento = bundleRecebedor.getString("dataDeNascimento");
String genero = bundleRecebedor.getString("genero");
String identificadorEmHash = bundleRecebedor.getString("identificadorEmHash");
String telefone = receiverIntent.getStringExtra("telefone");
reference = FirebaseDatabase.getInstance().getReference().child("Usuarios").child(identificadorEmHash);
Toast.makeText(getApplicationContext(), identificadorEmHash, Toast.LENGTH_LONG).show();
if(identificadorEmHash.equals(null)) {
Toast.makeText(getApplicationContext(), "The identifier does not exist", Toast.LENGTH_LONG).show();
} else {
reference.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
reference = FirebaseDatabase.getInstance().getReference().child("Usuarios").child(identificadorEmHash);
if (!dataSnapshot.exists()) {
Toast.makeText(getApplicationContext(), "The identifier does not exist", Toast.LENGTH_LONG).show();
} else {
HashMap<String, String> sendDataToDataBase = new HashMap<>();
sendDataToDataBase.put("Nome Completo", nomecompleto);
sendDataToDataBase.put("E-mail", email);
sendDataToDataBase.put("Identificador em Hash", identificadorEmHash);
sendDataToDataBase.put("Telefone", telefone);
sendDataToDataBase.put("Doenças Pré Existentes", doencasPreExistentes);
sendDataToDataBase.put("Data de Nascimento", dataDeNascimento);
sendDataToDataBase.put("Gênero", genero);
// When I am going to send the following data to Firebase, the problem of the video happens.
sendDataToDataBase.put("Região do Estado em que mora", regiaoDoEstado);
sendDataToDataBase.put("Raça", raça);
sendDataToDataBase.put("Estado do Brasil em que mora", estado);
try {
raiz.child(identificadorEmHash).setValue(sendDataToDataBase);
} catch (Exception e) {
e.getMessage();
}
}
}
});
}
}
});
Please, can someone help me to fix this bug?
Firebase doesn't automatically delete data, so if you see the data show up in the console it was written there by a client/API call, and allowed by your security rules. If the data subsequently gets updates or removed again, there is another client/API call that does so.
I recommend checking for realtime listeners in your code, that may be responding to your first write by updating (and accidentally reverting) that operation. It is also quite common to have a server-side script that is doing this.
Update: one thing you can try is to use updateChildren instead of setValue in all places such as this one:
raiz.child(identificadorEmHash).updateChildren(sendDataToDataBase)
I have a wearable app. The app after it finishes has data like time/date, UUID, Geo location, parameters selected displayed in front of me like a Data Report or Log in several TextViews underneath each other. Like a list. I want this data to be transferred from my wearable device to my android phone.
Now I have to ask does the WearOS app the pairs the phone with the watch enables such a thing? Like can the data be sent through it? OR what exactly can I do? I read about Sync data items with the Data Layer API in the documentation, but I'm not sure if the code snippets provided would help achieve what I want.
public class MainActivity extends Activity {
private static final String COUNT_KEY = "com.example.key.count";
private DataClient dataClient;
private int count = 0;
...
// Create a data map and put data in it
private void increaseCounter() {
PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");
putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);
PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
Task<DataItem> putDataTask = dataClient.putDataItem(putDataReq);
}
...
}
The data I display in the textviews are called through methods that I call things like: getLocation, getUUID, getDateTime, getSelections, etc... when I click a button I call them in the setOnClickListener. I want this data in the TextViews to be placed in a file or something like that and send them over to the mobile phone from the watch when they're generated.
private void getDateTime()
{
SimpleDateFormat sdf_date = new SimpleDateFormat("dd/MM/yyyy");
SimpleDateFormat sdf_time = new SimpleDateFormat("HH:mm:ss z");
String currentDate= sdf_date.format(new Date());
String currentTime= sdf_time.format(new Date());
textView_date_time.setText("Date: "+currentDate+"\n"+"Time: "+currentTime);
}
#SuppressLint("SetTextI18n")
private void getUUID()
{
// Retrieving the value using its keys the file name
// must be same in both saving and retrieving the data
#SuppressLint("WrongConstant") SharedPreferences sh = getSharedPreferences("UUID_File", MODE_APPEND);
// The value will be default as empty string because for
// the very first time when the app is opened, there is nothing to show
String theUUID = sh.getString(PREF_UNIQUE_ID, uniqueID);
// We can then use the data
textView_UUID.setText("UUID: "+theUUID);
}
#SuppressLint("SetTextI18n")
private void getSelections()
{
textView_data_selected.setText("Tool No.: "+c.getToolNo()+
"\nTool Size: " +c.getToolSizeStr()+
"\nFrom Mode: " +c.getCurrentModeStr()+
"\nGoto Mode: " +c.getModeStr()+
"\nMethod: " +c.getMethodStr()+
"\nBit Duration: " +c.getBitDuration()+
"\nUpper bound" +c.getUpStageValue()+
"\nLower bound: "+c.getDownStageValue());
}
The above are examples of the methods I use to get the data. then I call them here:
gps_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= 26) {
getLocation();
getDateTime();
getUUID();
getSelections();
}
else
{
//ActivityCompat.requestPermissions(get_location.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
Toast.makeText(get_location.this,"Build SDK too low",Toast.LENGTH_SHORT);
}
}
});
Now how do I take all this and send it over from my device to the the phone?
Note: The data report I want to send as a file, I want it done subtly like something done in the background. I don't know what else to do or where to look.
You have two options if you want to use the Data Layer, one is to use the MessageClient API to bundle your data up in a message and send it directly to the handheld. The easiest here would be to create an arbitrary JSONObject and serialize your data as a JSON string you can stuff into a message. For example:
try {
final JSONObject object = new JSONObject();
object.put("heart_rate", (int) event.values[0]);
object.put("timestamp", Instant.now().toString());
new MessageSender("/MessageChannel", object.toString(), getApplicationContext()).start();
} catch (JSONException e) {
Log.e(TAG, "Failed to create JSON object");
}
In my case, I do this in my onSensorChanged implementation, but you can insert this wherever you are updating your text.
MessageSender is just a threaded wrapper around the MessageClient:
import java.util.List;
class MessageSender extends Thread {
private static final String TAG = "MessageSender";
String path;
String message;
Context context;
MessageSender(String path, String message, Context context) {
this.path = path;
this.message = message;
this.context = context;
}
public void run() {
try {
Task<List<Node>> nodeListTask = Wearable.getNodeClient(context.getApplicationContext()).getConnectedNodes();
List<Node> nodes = Tasks.await(nodeListTask);
byte[] payload = message.getBytes();
for (Node node : nodes) {
String nodeId = node.getId();
Task<Integer> sendMessageTask = Wearable.getMessageClient(context).sendMessage(nodeId, this.path, payload);
try {
Tasks.await(sendMessageTask);
} catch (Exception exception) {
// TODO: Implement exception handling
Log.e(TAG, "Exception thrown");
}
}
} catch (Exception exception) {
Log.e(TAG, exception.getMessage());
}
}
}
The other option is to create a nested hierarchy of data items in the Data Layer and implement DataClient.OnDataChangedListener on both sides, such that changes that are written in on one side are automatically synchronized with the other. You can find a good walkthrough on how to do that here.
For your specific case, just packing it in a JSON object would probably be the simplest. The writing out to your preferred file format you can then implement on the handheld side without needing to involve the wear side.
I'm implement Razorpay with PaymentResultWithDataListener. Actually i need order_id and signature so i use PaymentResultWithDataListener not used PaymentResultListener because there are no option to get order_id and signature. And I have follow these links
https://docs.razorpay.com/v1/page/orders#verifying-the-signature
https://razorpay.com/mobile/
https://github.com/razorpay/razorpay-android-sample-app
But not getting any solution.
Menifest File
<meta-data
android:name="com.razorpay.ApiKey"
android:value="rzp_test_PLbERPkkqGZkOF" />
build.gradle
api 'com.razorpay:checkout:1.5.4'
I got an error
{"code":"BAD_REQUEST_ERROR","description":"ay_order_id is not a valid id"}
I am trying with this code
public class CheckoutActivity extends AppCompatActivity implements View.OnClickListener, PaymentResultWithDataListener {
private static final String TAG = CheckoutActivity.class.getSimpleName();
Button mCheckOutView;
String OrderId = "";
String signature = "";
String order_id = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_payment_method);
Checkout.preload(getApplicationContext());
mCheckOutView = findViewById(R.id.check_out);
mCheckOutView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (v == mCheckOutView) {
startPayment();
}
}
public void startPayment() {
/*
You need to pass current activity in order to let Razorpay create CheckoutActivity
*/
final Activity activity = this;
final Checkout co = new Checkout();
try {
JSONObject options = new JSONObject();
options.put("name","Test");
options.put("description", getString(R.string.app_name));
options.put("key", getString(R.string.api_key));
options.put("order_id","razorpay_order_id");
options.put("signature","razorpay_signature");
options.put("currency", "INR");
options.put("amount", 100);
JSONObject preFill = new JSONObject();
preFill.put("email", "test#gmail.com");
preFill.put("contact", "9999999999");
options.put("prefill", preFill);
JSONObject notesData=new JSONObject();
notesData.put("Order Id","order123");
notesData.put("address","Test Address");
options.put("notes", notesData);
JSONObject theme=new JSONObject();
theme.put("color","#738598");
theme.put("emi_mode",true);
options.put("theme", theme);
co.open(activity, options);
} catch (Exception e) {
Toast.makeText(activity, "Error in payment: " + e.getMessage(), Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
#Override
public void onPaymentSuccess(String s, PaymentData paymentData) {
String paymentId = paymentData.getPaymentId();
String signature = paymentData.getSignature(); // got null
String orderId = paymentData.getOrderId(); // got null
}
#Override
public void onPaymentError(int i, String s, PaymentData paymentData) {
Log.e(TAG,s); //error {"code":"BAD_REQUEST_ERROR","description":"ay_order_id is not a valid id"}
}
}
If i remove these 2 lines then this error not comes.
options.put("order_id","razorpay_order_id");
options.put("signature","razorpay_signature");
But paymentData.getSignature() and paymentData.getOrderId() is null.
Any help will be appreciated.
options.put("order_id","**razorpay_order_id**");
you need to generate this order_id from razorpay Order_ID API, only after this order_id which comes as a response from the API you would be able to process smoothly. After getting this Order_id from API, send it in above code in value (in place of razorpay_order_id)
options.put("signature","razorpay_signature");
This is not required in request. This will be generated at your server and will be used when a response is received in PaymentResultWithDataListener function. Read Signature generation method in official Documentation here : https://razorpay.com/docs/payment-gateway/android-integration/standard/
According to the official docs, by the time you start the checkout, you get the order_id when the merchant's backend starts an order with the RazorPay backend.
See the diagram here`.
As for the signature, according with the docs that's not something you put but something that comes from server responses and which you have to validate on your end. Check this
I need a working example for a custom API for Microsoft Azure App Service.
I could not get any useful or working information/examples for that, or they just show each time different approaches which are outdated?!?!
For now I have a working table controller which gets information from database and returns it back to my Android client. Now I need to define a custom API Controller to get a string back. In the examples they are all sending an object to the service in order to get an object back. I do not want to send anything to the API, just retrieve some information back from a GET Request.
Regards
// EDIT - Added / edited client / server code to Post a String.
You can use the following code to do a GET request on the auto generated API controller Visual Studio creates (ValuesController).
private void getStringFromAzure() throws MalformedURLException {
// Create the MobileService Client object and set your backend URL
String yourURL = "https://yourApp.azurewebsites.net/";
MobileServiceClient mClient = new MobileServiceClient(yourURL, this);
// Your query pointing to yourURL/api/values
ListenableFuture<JsonElement> query = mClient.invokeApi("values", null, GetMethod, null);
// Callback method
Futures.addCallback(query, new FutureCallback<JsonElement>() {
#Override
public void onSuccess(JsonElement jsonElement) {
// You are expecting a String you can just output the result.
final String result = jsonElement.toString();
// Since you are on a async task, you need to show the result on the UI thread
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(mContext, result, Toast.LENGTH_LONG).show();
}
});
}
#Override
public void onFailure(Throwable throwable) {
Log.d(TAG, "onFailure: " + throwable.getMessage());
}
});
}
public void sendString(final String someString) throws MalformedURLException {
// Your query pointing to /api/values/{String}
ListenableFuture<JsonElement> query = mClient.invokeApi("values/" + someString, null, PostMethod, null);
// Callback method
Futures.addCallback(query, new FutureCallback<JsonElement>() {
#Override
public void onSuccess(JsonElement jsonElement) {
// You are expecting a String you can just output the result.
final String result = jsonElement.toString();
}
#Override
public void onFailure(Throwable throwable) { }
});
}
The backend API: (ValuesController)
{
// Use the MobileAppController attribute for each ApiController you want to use
// from your mobile clients
[MobileAppController]
public class ValuesController : ApiController
{
// GET api/values
public string Get()
{
return "Hello World!";
}
// POST api/values/inputString
public string Post(string inputString)
{
return inputString;
}
}
}
You can also send parameters along in the following way:
List<Pair<String, String>> parameters = new ArrayList<>();
parameters.add(new Pair<>("name", "John"));
parameters.add(new Pair<>("password", "fourwordsalluppercase"));
ListenableFuture<JsonElement> query = client.invokeApi("yourAPI", PostMethod, parameters);
Or as json in the body:
JsonObject body = new JsonObject();
body.addProperty("currentPassword", currentPassword);
body.addProperty("password", password);
body.addProperty("confirmPassword", confirmPassword);
ListenableFuture<JsonElement> query = mClient.invokeApi("yourAPI", body, PostMethod, null);
Based on my understanding, I think there are two parts in your question which include as below. And I think you can separately refer to two sections to get the answers and write your own example.
How to define a custom API on Azure Mobile App to retrieve data from database? Please refer to the section Custom APIs to know how to do with Azure Mobile App backend.
How to call a custom API from Android App? Please refer to the section How to: Call a custom API to know how to do with Android SDK.
I have created my android code wherein I fetch all the data from facebook and then displays it in a textView and it works just fine on my account. But after I tried to connect with my dummy account, no details is fetched and I don't know the cause of this problem. Well here's my code to review:
private void getFbName() {
mProgress.setMessage("Finalizing ...");
mProgress.show();
new Thread() {
#Override
public void run() {
String name = "";
int what = 1;
try {
String me = mFacebook.request("me");
JSONObject jsonObj = (JSONObject) new JSONTokener(me).nextValue();
name = jsonObj.getString("first_name") + "|" + jsonObj.getString("last_name") + "|" + jsonObj.getString("email") + "|" + jsonObj.getString("id");
what = 0;
}
catch (Exception ex) {
ex.printStackTrace();
}
mFbHandler.sendMessage(mFbHandler.obtainMessage(what, name));
}
}.start();
}
private Handler mFbHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
mProgress.dismiss();
if (msg.what == 0) {
String username = (String) msg.obj;
username = (username.equals("")) ? "No Name" : username;
//SPLITTER
String tokens[] = username.split("\\|");
TextView fname = (TextView) findViewById(R.id.textView1);
fname.setText(tokens[0]);
TextView lname = (TextView) findViewById(R.id.textView2);
lname.setText(tokens[1]);
TextView eadd = (TextView) findViewById(R.id.textView3);
eadd.setText(tokens[2]);
TextView fbid = (TextView) findViewById(R.id.textView4);
fbid.setText(tokens[3]);
SessionStore.saveName(username, Main.this);
//mFacebookBtn.setText(" Facebook (" + username + ")");
Toast.makeText(Main.this, "Connected to Facebook as " + username, Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(Main.this, "Connected to Facebook", Toast.LENGTH_SHORT).show();
}
}
};
Well I only followed this tutorial for my code with some modification in the design wherein I use 1 button for login and another for logout and then displays the result in 4 textViews.
Edit
Here's my logout code:
private void fbLogout() {
mProgress.setMessage("Disconnecting from Facebook");
mProgress.show();
new Thread() {
#Override public void run() {
SessionStore.clear(Main.this);
int what = 1;
try {
mFacebook.logout(Main.this);
what = 0;
}
catch (Exception ex) {
ex.printStackTrace();
}
mHandler.sendMessage(mHandler.obtainMessage(what));
}
}.start();
}
When using the facebook android SDK, you two have two types of authentication:
Using the SDK auth dialog which will ask the user for his email/password.
Using Single Sign-On (SSO) which will only work if the device has the facebook application (katana) installed. If that's the case, that app will be responsible for the authentication which creates a better user experience since the user is already signed in and does not need to reenter his credentials.
If you are following the tutorial then you are using SSO (if the app is installed of course), and because of that when ever you are using the facebook.authorize method you are asking the fb app to authorize your app for the current logged in user.
If you want another user to use your app you'll need the user to log out of the main facebook app.
You can use the sdk authentication and bypass the SSO as suggested here: How to disable Facebook single sign on for android - Facebook-android-sdk, but as I said before, I think it results in a bad user experience.
Another thing is that you keep implementing things using threads, but the facebook android SDK already gives you a helper class for that, it's the AsyncFacebookRunner which makes api requests asynchronously, read Async API Requests.