Like widget works, Comment widget does not: SEE UPDATE 2
I inherited a project which has a Graph 1.0 implementation. Users can log in with Facebook, and then Like and Comment on the site.
The authentication system (symfony/php) interacts directly with Facebook in order to identify the user so that, if they don't exist, a profile can be created or, if they do exist, they can be logged into the local system as well.
The Like and Comment widgets have been updated to use the 2.0 syntax:
window.fbAsyncInit = function() {
FB.init({
appId : 'KEY_HERE',
xfbml : true,
version : 'v2.3'
});
};
</script>
<script>(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/es_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
This seems to be working ok. Widgets are generated and, using my personal Facebook account, I can post and like and see the results on both this site and on Facebook.
Meanwhile, for authentication, the application generates an authorize url like this:
http://www.facebook.com/v2.3/dialog/oauth?client_id=API_KEY&redirect_uri=REDIRECT_URI&state=TOKEN&scope=SCOPE
Scope consists of the following:
'email', 'user_website', 'offline_access', 'status_update', 'publish_actions', 'publish_stream'
From the callback handler of that request, we retrieve the users Facebook profile and forward along to custom code for logging a user in, or registering them:
https://graph.facebook.com/v2.3/oauth/access_token?client_id=API_KEY&redirect_uri=REDIRECT_URI&client_secret=API_SECRET&code=CODE
This also appears to be working, as long as I'm using my personal FB profile. I can login and Comment and Like things.
When I log in using my Open Graph Test User, I can't Like or Comment. When try to post a comment, I get an error which simply states "Oops" in a lightbox/dialog. From my console, I get the following error:
for (;;);{"__ar":1,"error":1357010,"errorSummary":"Oops","errorDescription":"Something went wrong. We're working on getting it fixed as soon as we can.","payload":null,"bootloadable":{},"ixData":{},"lid":"0"}
Here's what appears to be a comprehensive list of error codes, but 1357010 is not listed:
[http://fbdevwiki.com/wiki/Error_codes][1]
So, the fundamental question is, why can my Open Graph Test User (configured to run the app in 2.0 mode) not interact with the widgets, while my personal FB profile can? Have I failed to properly upgrade the authentication system so that the 2.0 Test User isn't sufficiently privileged?
[UPDATE]
When my application logs a user in, there is no part of the FB dialog which permits a user to accept the permissions which are being requested. Regardless of whether I'm logged in with my personal account or the Graph Test User, I can Like a page and then, subsequently, Comment from the resulting dialog - that dialog requests permission to do so.
But, from the standard Comments widget, I'm never asked to grant permission to post - it just fails with error 1357010. Toggling on/off "Also post on Facebook" makes no difference.
Am I not authenticating in a 2.0 fashion?
[UPDATE 2]
It looks like my Open Graph Test User can Like a page, and then, after confirming, the user can Comment on the page form the resulting dialog from the Like widget.
However, from a Comment widget, the comment is not successful and I get the generic error code 1357010.
What do I need to do to authorize my OG Test User (v2.3 user) to submit comments from a standard Comments widget?
It's unclear what are the calls you are making and I believe by "Like and Comment Widgets" you are talking about custom ones that are powered by the API and not the official Facebook plugins.
So to the issue: test users CANNOT interact with real data as per the docs:
Each app can create a maximum of 2000 test users.
Test users can only interact with other test users, and not with real users on Facebook.com.
Test users cannot become a fan of a public Facebook Page or create content on them, such as writing on a Page's wall. A Test
user can however view and interact with any app tab on the Page
associated with the app that created them.
Test users are unable to reply to messages, even if the message was created by the test user.
Test accounts can only be accessed and used by any developer of the associated app.
Test users will only have 'Tester' privileges on the associated app. This means that they can use the app in Public Mode or
Development Mode, but cannot edit any technical settings or access
insights for that app.
Test accounts cannot be converted to normal user accounts.
If you are interacting with real data, this may not work. You could probably test this by creating a new test user and observe the results.
Related
I am getting an error message when attempting to use the Facebook API.
When I have Client OAuth Login enabled, Web OAuth Login enabled and a valid Oauth redirect URI set to http://localhost:8000/ the error I get is this when trying to log into Facebook with the correct App ID:
URL Blocked: This redirect failed because the redirect URI is not whitelisted in the app’s Client OAuth Settings. Make sure Client and Web OAuth Login are on and add all your app domains as Valid OAuth Redirect URIs.
Is there a particular setting or thing I have to put in code to get this to work correctly?
This is the code I've got:
$(window).load(function() {
if (window.cordova.platformId == "browser") {
facebookConnectPlugin.browserInit(MYAPPIDHERE);
}
});
And this:
facebookConnectPlugin.login(["user_likes"],
function(response) {
likes();
},
function(response) {
likes();
});
}
EDIT:
Added pictures of what is in the Facebook App, as well as the URL I am navigating from.
You might want to check for HTTP calls made by facebookConnectPlugin and see if the redirect_uri in the query string matches the one you have in your Facebook App settings as a valid redirect URI.
It might look something like this:
https://www.facebook.com/dialog/oauth?client_id={FB_APP_ID}&redirect_uri=http://localhost:8000/
EDIT:
There seems to be an issue with the redirect_url=http://static.ak.fbcdn.net/connect/xd_proxy.php#cb=f11b73fd18e512c# being used by facebookConnectPlugin. I checked the javascript code and it is using phonegap/plugin/facebookConnectPlugin/fbsdk.js, which seems to be the culprit.
When I used direct loading of FB SDK, it uses a different redirect_url=http://staticxx.facebook.com/connect/xd_arbiter/r/RYqXvcNXPI-.js?version=42. Replacing the previous redirect_url with this one solved the issue for me. It is possible that phonegap's fbsdk.js uses an outdated script.
Bottomline: It would be better to load FB SDK directly, as mentioned here. And according to FB docs, it would look like this:
<script>
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
Lastly, to enable debug logs, replace //connect.facebook.net/en_US/sdk.js to //connect.facebook.net/en_US/sdk/debug.js.
The Javascript API wont work on PhoneGap for the login.
Use this cordova plugin instead.
https://github.com/Wizcorp/phonegap-facebook-plugin
It is impossible for Facebook to redirect to a local URL. What will happen is that you redirect a user to Facebook, they login, Facebook validates this and sends them back to you. Facebook sends them to the URL you provide. The URL http://localhost:8000 is a shorthand for: connect to port 8000 on your own machine. At the point where Facebook does the redirect, localhost refers back to Facebook, not you anymore. Apparently, Facebook has blacklisted that stuff - probably for security reasons.
What you need is a public URL that Facebook can redirect to. Maybe this helps?
Try these things:
set the URI to http://localhost/ (no port)
put a callback at the redirectURI with a corresponding callback function. i.e., http://localhost/loginCallback
Report back with any errors, I have a feeling the 1st way will work.
When calling FB.getLoginStatus using a valid Facebook App the response status is always unknown. Exact response is {authResponse: undefined, status: "unknown"}.
<html>
<body>
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function(){
FB.init({ appId:'1484134468466778', status:true, cookie:true, xfbml:true});
FB.getLoginStatus(function(response){
console.log(response);
});
};
(function(d){
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
d.getElementsByTagName('head')[0].appendChild(js);
}(document));
</script>
</body>
</html>
Example URL:
http://media.tuentifotos.com/simple_test.html
Here a screenshot of the Facebook App Settings.
This was happening for me in Chrome, and was because Chrome was configured to block third-party cookies and data.
Once I made that configuration change, FaceBook is able to log me into my app without a problem.
Chrome Settings
Show advanced settings...
Privacy
Content settings...
uncheck Block third-party cookies and site data
I too faced this problem in Chrome. However, in Firefox it worked as expected with the status returned as connected when the user had logged in previously.
I found a clue about this from an answer to the similar question here.
The root cause of this issue is, on FB.logout(), Chrome is not removing the cookie fblo_<your-app-id> which is somehow affecting FB.getLoginStatus() function to return unknown
Fix: On calling FB.logout(), you may programmatically delete the cookie fblo_<your-app-id>
FB.logout(function(response) {
deleteCookie("fblo_" + fbAppId); // fblo_yourFBAppId. example: fblo_444499089231295
});
function deleteCookie(name) {
document.cookie = name +'=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
}
When I checked, the status is showing "not_authorized" and that's fine, since I've not authorized the app yet.
To complete the flow, you should add the FB.login whenever user id is not authorized or not logged-in to facebook:
window.fbAsyncInit = function(){
FB.init({ appId:'{APP-ID}', status:true, cookie:true, xfbml:true});
FB.getLoginStatus(function(response){
if (response.status === 'connected') {
//proceed
} else if (response.status === 'not_authorized') {
login();
} else {
login();
}
});
};
function login(){
FB.login(function(response) {
if (response.authResponse) {
// proceed
} else {
// not auth / cancelled the login!
}
});
}
For me this meant "on my login page" I needed to specify cookies.
window.fbAsyncInit = function() {
FB.init({
version: 'v2.8',
cookie : true,
});
};
But don't ask me why this was the case. It also fixed it needing to click twice on the login button to actually login, and doesn't even require an appId, seemingly, FWIW...
The final answer
Ok so I think I've finally figured this damn issue out.
What you need to know:
1) You authenticate with Facebook via an app ID. This sets various cookies, where your app ID is tagged on the end:
fblo_000000000000
fbm_000000000000
fbsr_000000000000
2) If you delete these cookies, you're still authenticated to facebook as a regular user (unless you log out completely). And on Facebook's servers they still know you are authorized on this app.
So when you run FB.getLoginStatus() again it will just recreate them and put them back again. This is not what your user expects. This is bad. They clicked 'Log out'.
3) The docs explicitly say this:
The user is either not logged into Facebook or explicitly logged out of your application so it doesn't attempt to connect to Facebook and thus, we don't know if they've authenticated your application or not. (unknown)
So they don't even TRY to check if this cookie is set. That's why you get null or undefined. So the fblo cookie is considered like an 'opt-out'. You're NOT ACTUALLY LOGGED OUT by what any regular person would consider being logged out as to mean. There's just a cookie saying you are! Of course if the user logs back in with the login button then the cookie will be deleted, which is what you and your user wants.
Therefore I believe the only thing that makes sense to do (if you truly need to know the user's status) is to:
Manually check the existance of fblo_<APPID> cookie before you run FB.getLoginStatus.
If the cookie doesn't exist then do nothing and run your normal flow.
If the cookie does exist you have several options :
1) Option 1
Do absolutely nothing. You now understand the issue, you understand not to delete the cookie and perhaps you don't need to do anything other than show the Facebook login button.
2) Option 2
You assume the person is a user of your app, and do whatever you need to do to show the UI. But you won't be running your full normal logic - this will be application specific to you .
3) Option 3
Manually set the cookie value fblo_<APPID> to n (instead of 'y'). Remember this cookie is set on your domain so you're allowed to change it. *Depending upon your development environment this will vary, but it needs to be done client side, and you may need to specify path of `/' and your cookie domain).
Run the getLoginStatus(..., true) - it will not be blocked now because the cookie is now n. However you must not run your normal logic here - because all you want to do is check if the user is actually a Facebook user and/or still authenticated with your app.
Manually set the cookie value back to y
Unfortunately I can't recommend this solution due to weird race conditions. It almost almost works, but FB could deliberately or accidentally break it at any time - and it actually ends up still getting confused thinking you're really logged in when you aren't. Plus it could have all kinds of complications with other plugins I haven't even observed.
I wish the getLoginStatus would just always run and give accurate information, but this is the only true solution I see. And it's been this way for 8 years so I think we're stuck with it.
4) Option 4 - Set your own cookie
You always have the option to set your own cookies to indicate certain things, like 'this user has at some point logged into Facebook' or 'this user is authenticated with my app'. But I'm cautious about doing this because it can quickly get complicated.
Incidentally I revisited this issue because I'm using the Messenger plugin for my website and I don't want it to display at all unless I know the person has a Facebook account. So I need an accurate response to login status.
This was happening to me until I turn on my browser to allow third-party websites to save and read cookies.
To do this go to
settings > advanced > site settings > Cookies and site data
Then uncheck the option blocking third-party websites from saving and reading cookies.
This might not be a good option but it solves these issues for me.
You just need make your site URL from http to https
DO NOT use http
I had the same issue in IE. Flimzy's answer got me thinking. I tried running IE as administrator and it worked.
I had the same problem, I fixed this by clearing all cache and cookies.
You have to test it from the live domain (which you provided in the app).
I had the same problem when testing locally (using local domain).
In my case I was using Brave browser which didn't allow cookies due to which it was giving status unknown. I switched to chrome and now it is working.
I'm tearing my hair out here.
We've got a web app that is hosted on a bunch of different domains and we have a facebook login on the page. This works just peachy. Most of them run of our root domain eg newsite.ourplatform.com and we reuse the same facebook app and add a new domain in.
We've had a request to set up a new site on a different url. In the past, this hasn't really been a problem. We set up a new facebook app, add the appid to out config and voila, facebook login working. (we don't do this so often, so I've potentially broken it)
This time around. I've set up a new app id and plugged it in, but whenever I call the facebook login, it authenticates me, but I get a useless response from facebook.
eg. On a working site I call
FB.api("/me/", function(response){console.log(JSON.stringify(response));});
and get response
"{id":"12345678910","email":"my#email.com","first_name":"My Name","gender":"male","last_name":"Myname","link":"https://www.facebook.com/app_scoped_user_id/12345678910/","locale":"en_GB","name":"My Name","timezone":10,"updated_time":"2014-01-19T10:44:20+0000","verified":true}
but on the broken site I do the same call and get a response
{"name":"MyName","id":"12345678910"}
Which is sort of good, but I need their email. As far as I can tell, I'm not asking for any permissions beyond email,public_profile and user_friends
Because of the way the app setup works, we have different apps running 2.1, 2.2 and 2.4 and this new one on 2.4 doesn't work. I'm not sure if that's a red herring or if I've got a misconfigured facebook app.
(edit - removed the sites affected to protect the innocent)
As #CBroe said you really need to checkout the v2.4 changelog for the API. In version 2.4 of the API Facebook introduced 'declarative fields'. This means that when you make a base request, like to /me you will only get a small amount of info back, e.g. 'name' and 'id'.
You have two options to get more fields:
Option One
FB.api('/me?fields=first_name,last_name,gender', function(response) {
console.log(response)
});
Option Two
FB.api('/me', function(response) {
console.log(response)
}, {'fields': 'first_name, last_name, gender'})
This will return a response that looks like the following:
{"first_name":"First", "last_name":"Last", "gender":"gender", "id":"ID"}
The key in the request above is specifying the fields URL parameter in your request and is documented in the link #CBroe linked and I have linked above.
Friends,
I have set up a facebook login for my website using JS SDK.
If the use is logged in through JS SDK, should we cross verify whether the session is valid in the server side also as client side can easily be fabricated.
Since I use JS SDK, server will not have access to the facebook session.
If I need to verify the session at the server end, can i use php-sdk adn extern the session like it is specified in https://developers.facebook.com/docs/reference/php/ ? In this case I need to enable CURL PHP extension to get this running and worried if performance will go down when using php sdk.
Could you please help me in finding answers for the above queries?
The php sdk and the javascript are the completely opposite, of what Julian H. Lam said, in fact they were build to be used together.
On the php sdk documentation you can find this:
Integration with the Facebook SDK for JavaScript
Used in conjunction with the Facebook SDK for JavaScript, the PHP SDK
can share user sessions seamlessly across the client and server. If a
user is logged in with Facebook and has authorized your app, the
JavaScript SDK can pick up the user session persist this in a cookie
which, which the PHP SDK reads without any intervention on the
developer's part.
To enable this functionality, ensure that when you embed and
initialise the JS SDK, you set both the status and the cookie
parameters of the object passed to FB.init() to true.
And by using basic logic this makes all sense, on the client side you can create listeners to retrieve user status(if he's logged in, if he has granted permissions, if he has logout), doing this kind of actions on the server side doesn't make any sense at all.
So my advice for you is to use Javascript SDK to handle user events, like the ones I mentioned before, and to handle the responses from the actions of the users, like when the user does a like, or shares a post using the feed dialogue, etc.
With the php SDK you just check if you have a valid user, since you're sharing the same cookie for the client side and for the server side after you handle the login proccess with the javascript SDK, if you do this $fb_id = $facebook->getUser() (after initializing the PHP SDK of course), you'll get the user facebook id, now that you know you have a valid user, you can use the PHP SDK to query information about the user, post on user behalf, etc.
Here's an example of a proper loading of the javascript SDK with cookie support:
<div id="fb-root"></div>
<script>
window.fbAsyncInit = function() {
// init the FB JS SDK
FB.init({
appId : 'YOUR_APP_ID', // App ID from the app dashboard
channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel file for x-domain comms
status : true, // Check Facebook Login status
xfbml : true, // Look for social plugins on the page
cookie : true
});
// Additional initialization code such as adding Event Listeners goes here
};
// Load the SDK asynchronously
(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/all.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
And this is a simple code on the server side just to enlighten you:
require_once("facebook.php");
$config = array();
$config[‘appId’] = 'YOUR_APP_ID';
$config[‘secret’] = 'YOUR_APP_SECRET';
$config[‘fileUpload’] = false; // optional
$facebook = new Facebook($config);
try {
$user_profile = $facebook->api('/me','GET');
$user_name = $user_profile['name'];
$user_email = $user_profile['email'];
} catch(FacebookApiException $e) {
// If the user is logged out, you can have a
// user ID even though the access token is invalid.
// In this case, we'll get an exception, so we'll
// just ask the user to login again here.
}
PS: this server side code, only works if the user has already granted permissions with the scope email
There are two parts to this question: Firstly, there is a difference in the UI flow. See: https://developers.facebook.com/docs/concepts/login/login-architecture/
1) Browser side with JS SDK. You start off with oauth 2.0 dialog, obtaining the Access Token and then using this to access the Facebook API.
2) Server side uses signed_request posted to the server. With this, you can extract the user_id. See: https://developers.facebook.com/docs/howtos/login/signed-request/ -
Step 1 - describe the signed_request, how you can obtain it from PHP or JS SDK
Step 2 - how to verify that the signed_request is not fabricated.
Oauth token from other providers can be integrated with FB. See my Dropbox example: apps.facebook.com/fileglu/ - circa Sept 2011, also check out the technical section for implementation details, including CSRF, CORS and avoiding javascript cryptography.
The Facebook javascript library and the php SDK can essentially be considered two entities that do not talk to one another, as one is client-side, and the other is server-side.
The php SDK gives you greater fine-grained control over a user's login session, while the javascript library is easier to get started.
Typically, a user logged in via the javascript library is not automatically logged in on the server side, although in some cases, it may be possible to send the access token from client to server side. It is not advised, however, as this data can be intercepted.
This related question talks about sending the access token (as retrieved from the JS library) to the server side.
In essence:
FB.login(function(response) {
var access_token = response.authResponse.accessToken;
// Make an ajax call here to your server-side, and send access_token in.
});
I have a Facebook app that is built as an iFrame. I am using the JavaScript client API loaded via:
http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php
In my initialization code, I use the requireLogin method to ensure that the user has authorized the app. I have found this to be necessary to be able to gather the user's name, avatar, etc. for the scoreboard. Here's a representative code snippet:
FB_RequireFeatures(["Connect","Api"], function() {
FB.Facebook.init("...API_KEY_HERE...", "xd_receiver.htm");
var api = FB.Facebook.apiClient;
api.requireLogin(function() {
api.users_getInfo(
FB.Connect.get_loggedInUser(),
["name", "pic_square", "profile_url"],
function(users, ex) {
/* use the data here */
});
});
});
This causes the iframe to redirect causing the Facebook authorization screen to load within my app's iFrame. This looks junky and is somewhat confusing to the user, e.g. there are two Facebook bars, etc.
Question 1: is there anything I can do to clean this up while still implementing as an iFrame, and still using the JavaScript APIs?
According to the FB API documentation:
FB.ApiClient.requireLogin
This method is deprecated - use
FB.Connect.requireSession instead.
My experience though when I replace api.requireLogin with FB.Connect.requireSession it never gets invoked. I'd prefer the recommended way of doing it but I struggled and was not able to find a way to get it to work. I tried adding various arguments for the other two parameters as well with seemingly no effect. My expectation is that this method will load in a dialog box inside my app iFrame with a similar authorization message.
Question 2: what am I missing with getting FB.Connect.requireSession to properly prompt the user for authorization?
Finally, at the end of the game, the app prompts the user for the ability to publish their score to their stream via FB.Connect.streamPublish. Which leads me to...
Question 3: am I loading the correct features? Do I need both "Api" and "Connect"? Am I missing any others?
Here is a summary of the changes I needed to make to clean up the authorization process. It appears that iFrames must fully redirect to properly authorize. I tried using the FBConnect authorization but it was a strange experience of popup windows and FBConnect buttons.
Ultimately this game me the expected experience that I've seen with other FB apps:
FB_RequireFeatures(["Connect","Api"], function() {
var apiKey = "...",
canvasUrl = "http://apps.facebook.com/...";
function authRedirect() {
// need to break out of iFrame
window.top.location.href = "http://www.facebook.com/login.php?v=1.0&api_key="+encodeURIComponent(apiKey)+"&next="+encodeURIComponent(canvasUrl)+"&canvas=";
}
FB.Facebook.init(apiKey, "xd_receiver.htm");
FB.ensureInit(function() {
FB.Connect.ifUserConnected(
function() {
var uid = FB.Connect.get_loggedInUser();
if (!uid) {
authRedirect();
return;
}
FB.Facebook.apiClient.users_getInfo(
uid,
["name", "pic_square", "profile_url"],
function(users, ex) {
/* user the data here */
});
},
authRedirect);
});
For iFrames, the solution was ultimately to redirect to the login URL which becomes the authorization URL if they are not already logged in.
I think that FB.requireSession only works from a FB connect site outside of
Facebook. If you're using an app hosted on apps.facebook.com use the php api
call instead,
$facebook = new Facebook($appapikey, $appsecret);
$facebook->require_login();
or link to the login page.
Of these methods to login
* Using the PHP client library
* Directing users to login.php
* Including the requirelogin attribute in a link or form
* Using FBML
only the first 2 are available to iframe apps hosted on apps.facebook.com
I think requirelogin and fbml only work with fbml canvas apps.
see
http://wiki.developers.facebook.com/index.php/Authorization_and_Authentication_for_Canvas_Page_Applications_on_Facebook
Question 1: is there anything I can do
to clean this up while still
implementing as an iFrame, and still
using the JavaScript APIs?
Question 2: what am I missing with
getting FB.Connect.requireSession to
properly prompt the user for
authorization?
Please have a look at this. This article discusses correct use of require session and provides links on how to implement that. And yes, you are right, the requireLogin has been deprecated and won't help any more.
Question 3: am I loading the correct
features? Do I need both "Api" and
"Connect"? Am I missing any others?
As far as I know, you can use both API and Connect together, basically you access Facebook's API with the help of JavaScript.
For iframe apps however, there is no great help and minimum support of API with some handful functionality available. See this for more info.
This causes the iframe to redirect
causing the Facebook authorization
screen to load within my app's iFrame.
This looks junky and is somewhat
confusing to the user, e.g. there are
two Facebook bars, etc.
Finally and personally I have not seen any iframe app requiring user to add the app first. This will create the problem of two bars you mentioned as quoted above.
The link I posted at the beginning of my answer has some useful links to get you started and decide the next-steps or possibly making changes to your apps.