This question is not a duplication of this question.I have tried the solution mentioned there but didn't get any luck.
I have added branch.io deep-linking to my app. To test the implementation I have created a link with parameter as described here
https://docs.branch.io/pages/apps/android/#test-deep-link
everything worked fine, but the problem is I can not access the added data from the json object as the json doesn't contain the key I added earlier. I was supposed to get a response like this:
{
"identity_id": "427469360685348303",
"link": "https://example.app.link?%24identity_id=427469360685348303",
"session_id": "429691081177874743",
"data": {
"$canonical_identifier": "item/1503684554354.28",
"$desktop_url": "http://example.com/home",
"$exp_date": 0,
"$identity_id": "427469360685348303",
"$og_description": "My Content Description",
"$og_image_url": "http://lorempixel.com/200/200/",
"$og_title": "46D6D28E-0390-40E4-A856-BD74F34D24C8",
"$publicly_indexable": 1,
"+click_timestamp": 1503684563,
"+clicked_branch_link": true,
"+is_first_session": false,
"+match_guaranteed": true,
"custom": "blue",
"random": "FE848A5B-78F7-42EC-A253-9F795FE91692",
"added": "1503684554354.33",
"~campaign": "new launch",
"~channel": "facebook",
"~creation_source": 3,
"~feature": "sharing",
"~id": 429691043152332059,
"~referring_link": "https://example.app.link/X7OsnWv9TF",
"~stage": "new person",
"~tags": [
"one",
"two"
]
}
}
But this the response I got:
{"+non_branch_link":"https:\/\/qr6x.test-app.link\/g5ynWCX7PI","+clicked_branch_link":false,"+is_first_session":false}
here is my code:
Branch branch = Branch.getInstance(context);
branch.initSession(new Branch.BranchReferralInitListener() {
#Override
public void onInitFinished(JSONObject referringParams, BranchError error) {
if (error == null) {
// params are the deep linked params associated with the link that the user clicked -> was re-directed to this app
// params will be empty if no data found
// ... insert custom logic here ...
try {
Log.e("myapp","no error");
Log.e("myapp", referringParams.toString());
String pictureID = referringParams.optString("asdasdasdasd", "");
if (pictureID.equals("")) {
Log.e("myapp","no ID");
}
else {
Log.e("myapp","ID "+pictureID);
}
} catch (Exception e) {
System.out.println(" " + e.toString());
}
} else {
Log.i("MyApp", error.getMessage());
}
}
}, intent.getData(), activity);
can anyone give any idea what I am doing wrong?
Jackie from Branch here.
The +non_branch_link typically happens whenever there is an error when creating a Branch Deep Link, or whenever the live_key/test_key get mixed up (i.e. clicking a test link with an app that's using your live key, or vice versa).
Can you confirm that you have the correct Branch test key in the AndroidManifest.xml of your staging app? Here's our documentation on Android app config.
If you continue to experience issues, feel free to send over your APK file to integrations#branch.io and I'd be happy to investigate further for you.
Related
I am using Retrofit 2.1.0 with Jackson to make an API call.
The remote api gives two different response one which has json object with string and one custom object. and another response cary only status and error message.like below
required response
{
"status": "success",
"data": {
"id": 79068,
"username": "neha.fren01#gmail.com",
"email": "neha.fren01#gmail.com",
"enabled": false,
"confirmation_token": "27090745",
"name": "ronem",
"premium": false,
"token": "nmdgZe5Put6kS1KC_KH5d8Tk-fZLxZ15bV5tahJwQlY",
"phone_verified": false,
"email_verified": false
}
}
error response
{
"status": "error",
"message": "Unable to create userERROR: Email you entered is invalid. Provide another email.\n"
}
I can handle the required response shown above.but cannot handle the error response.
Here is the code how I made call
call.enqueue(new Callback<RegisteredResponse>() {
#Override
public void onResponse(Call<RegisteredResponse> call, Response<RegisteredResponse> response) {
if (response.isSuccessful()) {
try {
EventBus.post(new Events.RegistrationResponseEvent(StaticStorage.REGISTRATION_IDENTIFIER, response.body()));
} catch (Exception e) {
e.printStackTrace();
// EventBus.post(new Events.ErrorEvent(StaticStorage.REGISTRATION_IDENTIFIER, response.errorBody().toString()));
}
}else{
// I want to handle error response here.but error response is present inside response.isSuccessful() block
}
}
#Override
public void onFailure(Call<RegisteredResponse> call, Throwable t) {
t.printStackTrace();
EventBus.post(new Events.ErrorEvent(StaticStorage.REGISTRATION_IDENTIFIER, StaticStorage.ERROR_IN_LOADING));
}
});
Even the response object is error response it always goes to
response.isSuccessful()
block
I am unable to solve this issue. I lost 2 hours searching solution.
I followed this link aswell
response.isSuccessful()
Retrofit is depend on what status code you are getting from the server. even in failure if server still sending you 200 responseCode then there is no way you will get it in onError
means your api call was successful and response came. Doesn't matter what response came from server. For that you have to manually parse response and check whether your Json object has error or success status.
As per my opinion you have to make the response universal for all the web service. like
Sucess
{
"status": true,
"data": {
"id": 79068,
"username": "neha.fren01#gmail.com",
"email": "neha.fren01#gmail.com",
"enabled": false,
"confirmation_token": "27090745",
"name": "ronem",
"premium": false,
"token": "nmdgZe5Put6kS1KC_KH5d8Tk-fZLxZ15bV5tahJwQlY",
"phone_verified": false,
"email_verified": false
}
"message": ""
}
Error
{
"status": false,
"data":{},
"message": "Unable to create userERROR: Email you entered is invalid. Provide another email.\n"
}
Please change to status boolean flag, you have to check status of the response. If it is true then response is sucessfull if false then there is some error in response.
response.isSuccessful()
instead of above you need to check the status code of the server response, if it is 200 then web service sucessfully called.
I am new to Firebase and I trying to implement it into an Android application. It was all going well until now. I have to check the records for duplicates before inserting them and even after the tons of tutorials I watched online I can't figure it out.
I tried with rules, but apparently I was not able to write them down in a way they would work. I tried with push(), but this was not working either.
At the moment this is the code that I have:
private void updateDatabase(String year, String courseOfStudent, String workshopGroup, String day, String time, String lecture){
try{
mDatabase.child("student-timetables").child("course-of-student").setValue(courseOfStudent);
mDatabase.child("student-timetables").child(courseOfStudent).child("year").setValue(year);
mDatabase.child("student-timetables").child(courseOfStudent).child(year).child("workshop-group").setValue(workshopGroup);
mDatabase.child("student-timetables").child(courseOfStudent).child(year).child(workshopGroup).child("day").setValue(day);
mDatabase.child("student-timetables").child(courseOfStudent).child(year).child(workshopGroup).child(day).child("time").setValue(time);
mDatabase.child("student-timetables").child(courseOfStudent).child(year).child(workshopGroup).child(day).child(time).child("lecture").setValue(lecture);}
catch (Exception e)
{
Toast.makeText(getContext(), "Internal error occurred, please try again.", Toast.LENGTH_LONG).show();
}
}
And the rules from the Firebase console:
{
"rules": {
".read": "true",
".write": "auth != null",
"course-of-student": {
"year": {
"workshop-group": {
"day":{
"time": {
".write": "!data.exists()"
}
}
}
}
}
}
}
As of now what happens is that if there is a lecture detail at a specific time and I try to create a new record for this time the previous one gets overwritten. I want to reject this and display a message instead.
Where am I wrong?
First, add "ListenerForSingleValueEvent", and only then save the data in Firebase (if not exist..)
For example:
mDatabase.child("student-timetables").child(courseOfStudent).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
if(!(snapshot.child("year").exist))
mDatabase.child("student-timetables").child(courseOfStudent).child("year").setValue(year);
else
Toast.maketext....."year exist.."
if(!(snapshot.child(year).child("workshop-group").exist))
mDatabase.child("student-timetables").child(courseOfStudent).child(year).child("workshop-group").setValue(workshopGroup);
else
Toast.maketext....."workshopGroup exist.."
}
}
I am working on a project in which I have to work with Azure Back end, I have inserted data into the table, but don't know how to get its response and where should I use Json parsing .. below is my code .. please guide me about this
mClient.getTable(TodoItem.class).insert(item, new TableOperationCallback<TodoItem>() {
public void onCompleted(TodoItem entity, Exception exception, ServiceFilterResponse response) {
if (exception == null) {
// Insert succeeded
Toast.makeText(getApplicationContext(),"yes", Toast.LENGTH_LONG).show();
} else {
// Insert failed
String msg=exception.getCause().getMessage();
Toast.makeText(getApplicationContext(), "No", Toast.LENGTH_LONG).show();
}
}
});
For information on using the Android client SDK for Azure Mobile Apps, see the following articles:
Create an Android app
Enable offline sync for your Android mobile app
How to use the Android client library for Mobile Apps
i am creating appointment using below code give "500 Internal Server Error"
i added all fields check it
Appointment objappointment = Appointment.build()
.setSubject("Android sub")
.setDescription("dis from device")
.setRegardingObjectId(new EntityReference("account", UUID.fromString("0717b8e2-d00a-e611-8115-c4346bdd11d1")))
.setOwnerId(new EntityReference("systemuser", UUID.fromString("3edb272d-2da7-4c89-9350-2f4bd4e1762b")))
.setStateCode(new OptionSetValue(0))
.setNew_Latitude(23.7845)
.setNew_Longitude(73.6574)
.setNew_City("Surat")
.setActualStart(mDate.getTime())
.setActualEnd(mDate1.getTime())
.setNew_ZipPostalCode("380060")
.setNew_Street1("Street1")
.setNew_Street2("Street3")
.setNew_street3("Street3")
.setNew_StateProvince("Gujarayt")
.setNew_CountryRegion("India")
.setNew_Latitude(23.7845)
.setNew_Longitude(73.6574)
.setStatusCode(new OptionSetValue(0))
.setPriorityCode(new OptionSetValue(2));
try {
RestOrganizationServiceProxy restService = new RestOrganizationServiceProxy(mOrgService);
restService.Create(objappointment,new Callback<UUID>() {
#Override
public void success(UUID uuid, Response response) {
log("sucess", uuid.toString());
}
#Override
public void failure(RetrofitError error) {
displayError(error.toString());
log("error", error.toString());
}
});
}
catch(Exception ex) {
displayError(ex.getMessage());
log("msg",ex.toString());
}
another entity create successfully using above code just got error in "Appoinment"
Could you get more details of the exception? 500 could be any exception. At least you know the request hit the server and it's failing on the CRM server side. Maybe a plugin or similar is raising the exception.
I think you have to pass the objectid to whom the annotation will be linked to (Account, Contact, or whatever...)
Is that on-premise or online CRM? If OnPremise you could enable includeExceptionDetailInFaults property in the web.config to at least get more details of the exception....
I'm making an app that should allow the user to register through its google account. I want to retrieve automatically as many profile infos as I can. I found this very interesting example, which would allow me to get many infos (see step 4 of that demo). Now, how do I use it on android? I saw many examples of how to get the authentication token with the AccountManager with Oauth2 (example), but I don't know what to do from there to make those calls and retrieve those infos. Also in that example the code is in javascript and I don't know how to port it properly to java...
I have already done the google dev console registration stuff.
Are Oauth2 and OpenID the same thing? If not, do I have to use either one OR the other?
Ok, done. As expected, I found all the infos in the docs, and using Google's Oauth2 Playground helped to understand what to send to https://www.googleapis.com/oauth2/v1/userinfo in order to receive the profile data.
In the end, it turns out we don't need to create a client ID in google's dev console to do this.
Now, to the code. The activity:
public class MainActivity extends Activity {
public Activity mContext;
private AccountManager accountManager;
private final String SCOPES = "oauth2:https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile";
private String authToken;
private GetProfileDataTask googleTask;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
mContext = this;
accountManager = AccountManager.get(mContext);
//other stuff here...
}
public void getProfileData() {
accountManager.getAuthTokenByFeatures(
"com.google",
SCOPES,
null, mContext, null, null,
new AccountManagerCallback<Bundle>() {
public void run(AccountManagerFuture<Bundle> future) {
try {
Bundle bundle = future.getResult();
//bundle.getString(AccountManager.KEY_ACCOUNT_NAME);
//bundle.getString(AccountManager.KEY_ACCOUNT_TYPE);
authToken = bundle.getString(AccountManager.KEY_AUTHTOKEN);
} catch (Exception e) {
System.out.println("getAuthTokenByFeatures() cancelled or failed:");
e.printStackTrace();
authToken = "failure";
}
if(!authToken.equals("failure")) {
googleTask = new GetProfileDataTask();
googleTask.execute(authToken);
}
}
}, null);
}
}
The AsyncTask that gets the data:
public class GetProfileDataTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... tokens) {
RestTemplate restTemplate = new RestTemplate(false);
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
String json = null;
try {
//the response is of type "application/json"
json = restTemplate.getForObject(
"https://www.googleapis.com/oauth2/v1/userinfo" +
"?access_token={token}" +
"&access_token_type=bearer",
String.class,
tokens[0]); //this is the authToken from before, obv
} catch(RestClientException er) {
Log.e("GetProfileDataTask", er.toString(), er);
json = null;
}
return json;
}
#Override
protected void onPostExecute(String asyncResult) {
if(asyncResult != null)
//do something with your data, for example deserialize it
else
//do something else
}
}
The received json is like this:
{
"family_name": "Smith",
"name": "John Smith",
"picture": "https://lh3.googleusercontent.com/-randomlettersandnumbers/AAAAAAAAAAI/AAAAAAAAAAA/morerandomlettersandnumbers/photo.jpg",
"locale": "it",
"gender": "male",
"email": "youremail#whatever.itis",
"link": "https://plus.google.com/133780085840848123456",
"given_name": "John",
"id": "133780085840848123456",
"verified_email": true
}
Since you want to allow user sign in your app via their Google accounts, you can use OpenID, and Google supports it.
Note: If you provide a “sign-in with Google” feature, we recommend using Google+ Sign-In.
If you just want get usr's info in Google on behalf of users, you can just use Oauth2. Refer to Google'a official documents, I think they are detailed, authoritative and easy to get along.
As this doc says:
5.Obtain user information from the ID token
An ID token is a cryptographically signed JSON object encoded in base 64. Normally, it is critical that you validate an ID token before you use it, but since you are communicating directly with Google over an intermediary-free HTTPS channel and using your client secret to authenticate yourself to Google, you can be confident that the token you receive really comes from Google and is valid.
So in a word, read these docs carefully and you'll get be clear about how to accomplish your app.