Is there any way generate identical links on different devices with Branch.io?
What I mean:
In the application I have post. I want to share this with friends. I click to share on one device and get a link
Then I want to share the same post from another device. I get the second link. They differ. But I need them to be the same.
If you use the exact same parameters to generate the link on both the devices it should generate the same link. If even one of the parameters you add to link is specific to the user/device etc. the value you provide for the Branch link will be different and hence a new link will be generated.
Also, if you are using setIdentity() in your application each link created will be tagged with the user Identity and hence will create a different link each time.
For example:
final BranchUniversalObject branchUniversalObject = new BranchUniversalObject()
.setCanonicalIdentifier("1234")
.setTitle("Test for link")
.setContentIndexingMode(BranchUniversalObject.CONTENT_INDEX_MODE.PUBLIC)
.setContentDescription("Your friend has invited you to check out my app!")
.setContentImageUrl("https://upload.wikimedia.org/wikipedia/commons/thumb/5/5a/Branch_Metrics_logo_color.png/1200px-Branch_Metrics_logo_color.png")
.addContentMetadata("var1", "abc")
.addContentMetadata("var2", "def");
LinkProperties linkProperties = new LinkProperties()
.setChannel("App")
.setFeature("Sharing")
.addControlParameter("$android_deepview", "branch_default");
branchUniversalObject.generateShortUrl(this, linkProperties, new Branch.BranchLinkCreateListener() {
#Override
public void onLinkCreate(String url, BranchError error) {
if (error == null) {
Log.v("url",url);
}
else {
Log.v("url",url);
}
}
});
The above will always generate the same link on any Android device. But is I am using Branch.getInstance().setIdentity(user_id) in my Android App it will generate a new link even if all the link parameters are the same.
Related
Android Platform
i use below code to generate and share the link in Facebook etc, and click it, it has record in " Summary ", but not show in Quick Link Dashboard.
val lp = LinkProperties()
.addControlParameter("\$deeplink_path","https://www.google.com")
val buo = BranchUniversalObject()
.setCanonicalIdentifier("item/abcd")
.setTitle("Hellow Title")
.setContentDescription("Hello Description")
.setContentIndexingMode(BranchUniversalObject.CONTENT_INDEX_MODE.PUBLIC)
.setLocalIndexMode(BranchUniversalObject.CONTENT_INDEX_MODE.PUBLIC)
buo.generateShortUrl(
activity, lp
) { url, error ->
if (error == null) {
// share intent
} else {
Logger.e("error: ${error.message}")
}
}
Using the code, this cannot show in the Quick Link Dashboard.
About the doc, it need add two params "type:2" and "$marketing_title", i set it to LinkProperties:
lp.addControlParameter("type", "2")
.addControlParameter("\$marketing_title", "android _test")
Or: BranchUniversalObject:
buo.setContentMetadata(ContentMetadata().addCustomMetadata("type", "2"))
.setContentMetadata(ContentMetadata().addCustomMetadata("\$marketing_title","android"))
But it not work, so, how to solve?
Thanks!
By default, your SDK-created links will not be visible on the Quick Links Dashboard. The specification of passing type:2 and setting a marketing title in the request payload is limited to API-created links only.
Understanding that you'd want to check the conversions, it is highly recommended to tag these branch links (e.g. channel = API/campaign=Promo) so that you can segment your data to see all installs/clicks from links created via the SDK on the Branch Dashboard Sources/Summary section.
Im trying to develop a sing up for AWS Cognito in Android. I just checked the official doc but in the Register a New User section there is only the sample for using SignUpHandler.
Checking other sections, for example Using the JavaScript SDK there is a clear sample using
userPool.signUp('username', 'password', attributeList, null, function(err, result)
Im trying to implement this aproach transpolating the javascript example. But I was wondering if there is any complete sample of sign up for Android?
Thanks in advance!!
The handler you noticed is a parameter for the call to sign up, much like 'function(err, result) in the JS example. Take a look at this part of the docs, it shows how to use that handler. From the example you screenshotted, it might look like this:
userPool.signUpInBackground(userId, password, userAttributes, null, handler);
Here is a complete sample using the link sugested by Jeff:
CognitoUserAttributes attributes = new CognitoUserAttributes();
attributes.addAttribute("phone_number","+15555555555");
attributes.addAttribute("email","email#mydomain.com");
cognitoUserPool.signUp('username', 'password', attributes, null, new SignUpHandler() {
#Override
public void onSuccess(CognitoUser cognitoUser, boolean b, CognitoUserCodeDeliveryDetails cognitoUserCodeDeliveryDetails) {
// If the sign up was successful, "user" is a CognitoUser object of the user who was signed up.
// "codeDeliveryDetails" will contain details about where the confirmation codes will be delivered.
}
#Override
public void onFailure(Exception e) {
// Sign up failed, code check the exception for cause and perform remedial actions.
}
});
The sections Examples of Using User Pools with the Mobile SDK for Android seems to be outdated.
Hope to help somebody else ;)
Authentication and app engine, there is a lot to be read about it, but a lot seems to be outdated!
Even the google pages https://developers.google.com/appengine/docs/java/endpoints/consume_android#making-authenticated-calls
Here, they talk about 'GoogleAccountCredential.usingAudience', but nowadays, you should use GoogleAuthUtil (as far as I know, please correct me if I'm wrong).
I am trying to set up an app engine as a backend to my Android app (and in future, my iOS app).
I am using Android Studio, used the 'new module' and chose app engine with cloud messaging there.
I created a simple endpoint, and have a function there, here is some code:
public class ReviewEndpoint {
// Make sure to add this endpoint to your web.xml file if this is a web application.
private static final Logger LOG = Logger.getLogger(ReviewEndpoint.class.getName());
/**
* This method gets the <code>Review</code> object associated with the specified <code>id</code>.
* #param id The id of the object to be returned.
* #return The <code>Review</code> associated with <code>id</code>.
*/
#ApiMethod(name = "getReview")
public Review getReview(#Named("id") Long id) {
// Implement this function
Review r = new Review();
r.setData("test!");
As you can see, this is nicely generated by Android Studio. I implemented some stuf like creating the 'review' object and return it at the end.
On the Android side, I can do this:
ReviewEndpoint.Builder b = new ReviewEndpoint.Builder(AndroidHttp.newCompatibleTransport(), new AndroidJsonFactory(), null);
ReviewEndpoint ep = b.build();
Review review = ep.getReview(1L).execute();
data = review.getData();
and yes, I get 'test!' :)
Now, I want to have this authenticated. I want to know which user wrote what, so I thought I am going to use GMail account and Facebook later.
Here I'm stuck. I am able to get a token from the user on Android:
token = GoogleAuthUtil.getToken(MainScreenActivity.this, mAccount.name, "oauth2:https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/userinfo.profile");
then you are able to add this token as credential to the request:
Credential cr = new Credential(BearerToken.authorizationHeaderAccessMethod()).setAccessToken(token);
ReviewEndpoint.Builder b = new ReviewEndpoint.Builder(AndroidHttp.newCompatibleTransport(), new AndroidJsonFactory(), cr);
Then in the app engine I tried to get the user info, but how?
Will it be supplied as 'bearer'? How do I get this bearer token? Should I then do API request to get the data on the server?
this does not work:
OAuthService service = OAuthServiceFactory.getOAuthService();
try {
User user = service.getCurrentUser();
can anyone give me a heads up?
So finally, today, I found out how to do it! I had questions on Stackoverflow on this before and never had an answer, but these to sites gave me the answer:
https://developers.google.com/appengine/docs/java/endpoints/auth
https://developers.google.com/appengine/docs/java/endpoints/consume_android
The first shows what needs to be done on the app engine side. The second page will tell you how to get the credentials. I was quite close. I am not sure if the adjusting of the build.gradle file mentioned in the second link is necessary. What I added to the App Engine:
#Api(name = "reviewEndpoint", version = "v1", ...<<some more stuff here >>
scopes = {Constants.EMAIL_SCOPE},
clientIds = {Constants.WEB_CLIENT_ID, Constants.ANDROID_CLIENT_ID},
audiences = {Constants.ANDROID_AUDIENCE})
and then get the credentials:
// Initialize the scope using the client ID you got from the Console.
final String scope = "server:client_id:" + Constants.WEB_CLIENT_ID;
credential = GoogleAccountCredential.usingAudience(activity,scope);
You have to add the e-mail address of the user:
credential.setSelectedAccountName("some-mail-address#gmail.com");
you can get the e-mail address using the account picker (also example shown when you follow the link)
and next. you do a call to the endpoint, using the credential, I think Play Services will validate the user, because if I use an e-mail that is not logged in on the device, it will not work. The following code will throw an GoogleAuthIOException :
ReviewEndpoint.Builder b = new ReviewEndpoint.Builder(
AndroidHttp.newCompatibleTransport(),
new AndroidJsonFactory(), id_token);
ReviewEndpoint ep = b.build();
Review review;
review = ep.getReview(1L).execute();
for testing, I've put the e-mail address I get at the server side as a string in the review object, and there it gave me the e-mail address instead of the user object being null. Ow! I forgot to tell you, you need a user argument on the app engine side. Even though you do not see the 'user' argument in the 'getReview' call above, it will be added by App Engine.
So this is how my getReview looks now:
#ApiMethod(name = "getReview")
public Review getReview(#Named("id") Long id, User user) {
// Implement this function
Review r = new Review();
r.setData("user == " + (user == null ? "NULL " : user.toString()));
Hope this will help someone
I am having trouble while trying to post a message on the current end-user Facebook wall with my Android Application.
So far :
The user is logged in with all the required permissions, especially
the publish_actions permission ;
I am using the last version of Facebook SDK 3.x & Graph API v2 as of May 2014
Post to wall works now as of EDIT 2, but there are issues with
privacy settings : post cannot be seen by anyone not even the
recipient who is tagged in the post ! See EDIT 2 for more details
Here is the documentation for posting a message on the user wall :
https://developers.facebook.com/docs/graph-api/reference/v2.0/user/feed (go to Publishing)
Regarding the message that needs to be posted on the user' wall, I need to tag some friends that were previously selected by the user.
But to use the tag field I need to use the place field.
The documentation says :
Name: tags
Comma-separated list of user IDs of people tagged in this post. You cannot specify this field without also specifying a place.
Type: csv[string]
Name: place
Page ID of a location associated with this post.
Type: string
What is location page ID ? How do I get it ?
Oddly enough, in my specefic case, I am offering the possibilty to the user to share is upcoming travel on Facebook.
More oddly enough, this travel is defined by dates and a destination (name of destination + latitude & longitude). The user has the possibility to also share this travel to his friends that are located in his travel's destination hence the need to tag his friends to the wall post.
[EDIT 1]
After looking into #Tobi solutions, I managed to post a message on the end-user wall (in my case me, since I am the developper).
So far : the message is correctly displayed with a friend tagged (a dummy account I use for tests purpouses) and there is also the place : Paris, France.
Using the following search query (thanks #Tobi) search?q=Paris,France&type=place I can get the ID of Paris, France.
Since I did not code the part to retrieve the Place ID it put it manually in the code for the sake of testing the feature first.
[END OF EDIT 1]
[EDIT 2]
I noticed I forgot to add the part with the privacy values to my args Bundle. But it did not change a damn thing : my post is only visible to me alone.
Going to my Facebook wall, here is what I get :
Hovering the public parameters of the posts (a padlock icon) says "All tagged persons".
Clicking on the icon shows the list of settings with only "Only me" selected.
Why "only me" even though I specifically said me + my dummy account in the request parameters ?
Even weirder : changing the property of the publication parameters to "customized" with my dummy account does not change a damn thing as well. Just why ? Facebook is really getting on my nerve...
For the rest, the message content is correctly displayed and the related place is the good one. At least a got that correctly. But still, I just don't get the rest ...
[END OF EDIT 2]
So here is the updated code :
if (this.session != null && this.session.isOpened()) {
final Bundle args = new Bundle();
if (this.selectedContacts.isEmpty() == false) {
args.putString("message", message);
args.putString("place", "170558129707208"); //manually added Paris, France ID
String tags = "";
//here I made some modifications regarding the tags so that is built correctly
for (int it = 0; it < this.selectedContacts.size(); it++) {
final String name = this.selectedContacts.get(it).toString();
final String friendID = String.valueOf(getIdFromName(name)); // returns an int
if (it == this.selectedContacts.size())
tags += friendID;
else
tags += friendID + ",";
}
// Forgot to add privacy values to bundle !
final JSONObject privacyValues = new JSONObject(); //not android JSON, but JSON-Simple lib
privacyValues.put("value", "CUSTOM");
String allow = this.currentUser.getId() + "," + tags;
privacyValues.put("allow", allow); // to limit the visibility of this post
args.putString("privacy", privacyValues.toJSONString()); //forgot that one...
final Request shareTravelRequest = new Request(this.session, this.currentUser.getID() + "/feed",
args, HttpMethod.POST, new Request.Callback() {
public final void onCompleted(final Response response) {
//TODO
}
}
);
final Response response = shareTravelRequest.executeAndWait();
if (response.getError() == null) // in this case, no error occurred
return true;
else {
this.lastErrorMessage = response.getError().getErrorMessage();
Log.e("Something went wrong while posting Facebook message", this.lastErrorMessage);
Log.e("Error type is", response.getError().getErrorType());
Log.e("Error code is", String.valueOf(response.getError().getErrorCode()));
return false;
}
}
}
Unfortunately I must have mistaken somewhere because although the post does appear on my Facebook wall with my dummy account tagged and with the correct link to the place, my dummy account cannot see the post.
I tried creating manually the same post on my Facebook wall by using the following settings :
First I supplied a message
Second I supplied a place
Third I tagged my dummy account
Four I choose who can see this post : me and my dummy account
And finally, I post the message.
In this case, my dummy account sees the post both on its wall and on my wall.
So I would like to know what parameters I must get wrong because there is not much parameters and I just don't see why.
Thanks !
You can either use the Search and use the type place (https://developers.facebook.com/docs/graph-api/using-graph-api/v2.0#search), or, if you have positioning date, use an FQL query on the place table (https://developers.facebook.com/docs/reference/fql/place/) as described here: Facebook places: order results by distance
Use two test accounts made via Facebook Developer App settings and not a dummy account that breaks TOS. Since you request publish_actions you probably didn't submit the app for review. Unless your dummy account is a developer/tester in roles as well (which is breaking the TOS again) then your dummy account will not be able to see the post.
Only developers and testers of an unpublished application can see posts made by that application.
I am working through the Facebook Wishlist app for Android. When I attempt to add my custom object to the Facebook graph the API returns the following error:
{
"error: {
"type": "OAuthExeption",
"message":"(#100)
Application does not own
230752723668296 action type"
}
}
I haven't been able to find any specific documentation on this particular error. Are there any Facebook developers out there who may be able to help me interpret this.
I should also mention that I already have a working example of this app running without errors (I am trying to duplicate it so I can tweak it with out fear of losing work). I have tried changing the name of the Action but this makes no difference. Below is the snippet of the Android code where it adds the item to the Facebook time line. This is however a small piece of the over all puzzle as there are three sides to this project (Facebook, My Server, and Android)
public void addToTimeline() {
dialog = ProgressDialog.show(Wishlist.this, "",getString(R.string.adding_to_timeline), true, true);
/*
* Create Product URL
*/
String productURL = HOST_SERVER_URL + HOST_PRODUCT_URI;
Bundle productParams = new Bundle();
productParams.putString("name", mProductName);
productParams.putString("image", mProductImageName);
productURL = productURL + "?" + Util.encodeUrl(productParams);
Bundle wishlistParams = new Bundle();
if(mPlacesAvailable) {
try {
wishlistParams.putString("place", mPlacesJSONArray.getJSONObject(mPlacesListSpinner.getSelectedItemPosition()).getString("id"));
} catch (JSONException e) {}
}
wishlistParams.putString("wishlist", WISHLIST_OBJECTS_URL[mWishlistSpinner.getSelectedItemPosition()]);
wishlistParams.putString("product", productURL);
wishlistParams.putString("image", mProductImageURL);
//TODO
//put the app's namespace and 'add_to' action here
Utility.mAsyncRunner.request("me/wishlisteight:adding_to", wishlistParams, "POST", new addToTimelineListener(), null);
}
"I should also mention that I already have a working example of this app running without errors (I am trying to duplicate it so I can tweak it with out fear of losing work)"
That action is specific to an app id. When you made the duplicate of your code, did you use the same app id or create a new one? If you created a new app id, you will need to register actions for the new app just like you did with the first app.
I encountererd this error (#100 Application does not own action type) when using the Graph API Explorer tool to post an action to my app's timeline. Here is a brief summary of the values I had entered when encountering this error and how I resolved the issue. Fyi, my app is called 'recipestogo'. The action I defined for my app is called 'cook', and the associated object is called 'recipe'.
Values I entered into Open Graph API:
Chose 'Post' from the drop-down
https://graph.facebook.com/me/recipestogo:cook?recipe=https://www.mywebsite.com/index.html
Error encountered:
100 Application does not own action type
Resolution:
At the top, right of the API Graph Explorer tool, there is a drop-down next to Application. It had been set by default to Graph API Explorer. Changing this from Graph API Explorer to RecipesToGo resolved the issue and I was able to successfully post to my app's timeline.