I haven’t tried this myself to check but:
Did you also include the tweet.read,users.read,bookmark.read,bookmark.write scopes too? Twitter API v2 authentication mapping | Docs | Twitter Developer Platform Just to eliminate that. Does GET /2/users/me | Docs | Twitter Developer Platform work?
Hey Igor - Yes, I actually added all of the possible scopes as well to see if it had anything to do with it. Didn’t work as well
1 Like
Also, just to confirm - is it indeed possible to just use a “bearer token” (not the application one) for OAuth 2 User context? Because I’m getting mixed signals from what i’ve read / seen. Would be good to confirm that it’s indeed possible.
1 Like
nvahnav
#6
I looked at Firebase SDK a couple weeks ago, and the pre-built Twitter login didn’t appear to support Oauth 2.0 PKCE flow, only OAuth 1.0 - trust but verify of course - and I didn’t go down their recommendation for custom auth, sorry. Supabase also doesn’t currently support Oauth 2.0 PKCE either, fwiw.
Cheers | van
So what did you do? Pass on it or find some alternate solution?
nvahnav
#8
@royherma
We’re not in prod yet and the app is Web; however, our beta impl uses Next w/ Auth.js, which has basic ( alpha? ) OAuth2 PKCE flow for Twitter OOB. For example, their adapter doesn’t manage refresh token expiry, but our code does of course. BaaS is interesting, and I’m always open to change, but I’m still more comfortable managing Cloud and NoSql with other solutions myself.
Now, someone may have a solution for PKCE auth code flow for Firebase. We’re currently avoiding any dark paths unless absolutely necessary. GL to you.
Cheers | van
Thank you for the response - will take a look!
Thanks - also found this, might be useful GitHub - OAuthSwift/OAuthSwift: Swift based OAuth library for iOS
Looks like can handle it all pretty solidly
2 Likes
So I attempted to also call the /me endpoint, but getting same error
'Authenticating with Unknown is forbidden for this endpoint. Supported authentication types are [OAuth 1.0a User Context, OAuth 2.0 User Context].',
This error makes sense to me - since from the examples on their docs and here, you can see the way they only make the request from this oauth2 user context types through a
//Gets access token
await authClient.requestAccessToken(code);
//Get the user ID
const {
data: { id },
} = await client.users.findMyUser();
Now, my flow is a bit different since the user is doing a log in via the iOS app, where I store the access token received via app and attempt to make calls to the oauth2 user context via a backend/api service i’ve set up.
I initially thought the access token we receive in app is sufficient for making the requests, but as per their examples there appears to be another request, to “exchange tokens” for a token that can be used to make the requests - I do that, an am actually successfully receiving a “bearer token” back, but I am not able to use that token (as a bearer) to make requests in the OAuth2 User Context (i get the same error as the first one i wrote on top).
My hunches are there could be a few things here:
- Firebase auth flow is not OAuth2, so the tokens we’re getting back are actually not valid at all
- Public vs Confidential client - perhaps there is something we need to switch there
3, Incorrectly using the API/sdk (im using PLhery’s node-twitter-api-v2 (on github) and perhaps I am not using it the right way (althought i closely followed instructions + docs, so doubt it)
LMK your thoughts and if my issue make sense - or if you know anyone that has implemented this via iOS on a native app! Thank you so much
Is there a way to dig in and see what request is actually being sent? the HTTP request? Because that looks like the authentication is just missing or otherwise malformed, and the Bearer token could be fine.
Public vs Confidential client
I guess technically you should be using Public Client since it’s an app, Confidential and Public Clients - OAuth 2.0 but i think the authentication is the error not the client type setting - but if that turns out to be it, do follow up - i haven’t tried it myself yet to see if it makes a difference.
This is an example of how i’m making the request to the “me” endpoiont
//create headers
const headers = {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + beareToken,
};
//create the request options
const options = {
method: 'GET',
headers: headers,
};
//make the request
const req = await fetch('https://api.twitter.com/2/users/me', options)
response is:
title: ‘Unsupported Authentication’,
detail: ‘Authenticating with Unknown is forbidden for this endpoint. Supported authentication types are [OAuth 1.0a User Context, OAuth 2.0 User Context].’,
type: ‘Twitter API Response Codes & Error Support | Twitter Developer Platform’,
status: 403
tell me if that helps in terms of showing request details
@IgorBrigadir BTW - if i try to use the access token i get from the app oauth (without exchanging tokens), i get this message:
req {
title: ‘Unsupported Authentication’,
detail: ‘Authenticating with OAuth 2.0 Application-Only is forbidden for this endpoint. Supported authentication types are [OAuth 1.0a User Context, OAuth 2.0 User Context].’,
type: ‘Twitter API Response Codes & Error Support | Twitter Developer Platform’,
status: 403
}
So two different responses. When i do attempt to “create the access token”, i get back such a response (which looks valid)
data {
token_type: ‘bearer’,
expires_in: 1296000,
access_token: ‘some_token_string’,
scope: ‘offline_access’
}
Maybe there is hint here?
BTW about this - where did you see the Twitter flow on Firebase doesn’t support OAuth2? I couldn’t find anything from firebase about it… would be good to confirm!
TY
You can script this @IgorBrigadir bc it appers I was using grant_type of client_credentials - which i guess only returns the application bearer. So this approach I tried to use the oauth_token to exchanges for a valid request token is not relevant and will likely not work.
In meantime, I’m going to re-build the flow using another library via the app - to make sure it is indeed doing an OAuth2 request (not firebase).
If you have any other ideas though, would be greatful!
@IgorBrigadir I just reimplemented via another iOS library that is 100% using oauth2.
This way I was able to get back a refresh token as well.
I then tried a basic sample request:
async runSampleAPIRequest(beareToken: string): Promise<any> {
const headers = {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + beareToken,
};
//create the request options
const options = {
method: 'GET',
headers: headers,
};
//make the request
const req = await fetch('https://api.twitter.com/2/tweets?ids=1617786868988530688', options)
.then((response) => {
// console.log('response', response);
return response.json();
})
.then((data) => {
console.log('data', data);
return data;
})
.catch((error) => {
console.error('error', error);
return error;
});
//print the req so we can see what was sent to the server
console.log('req', req);
return req;
}
I tried both using the original token i get back from the oauth2 pkce flow, as well as generating a new access token via the refresh token to make the call above.
I got kept getting either
sample_api_call {
title: ‘Forbidden’,
type: ‘about:blank’,
status: 403,
detail: ‘Forbidden’
}
or
sample_api_call {
title: ‘Unauthorized’,
type: ‘about:blank’,
status: 401,
detail: ‘Unauthorized’
}
Hopefully this details should help as well 
nvahnav
#18
It’s definitely an issue with your token and/or iOS lib.
fwiw, here’s essentially your same code jest tested using an OAuth2 Bearer token created for my app project and an OAuth2 PKCE access token created on app sign in. Both work.
Just a sanity check for you as you’ve probably tried this already. I know it doesn’t solve your problem, sorry.
Cheers | van
2 Likes
This should help - as long as i know its working…
So you used the same vanilla code on the left I attached?
My feeling (and i hope i’m wrong) is maybe bc i was testing on localhost, the requests were getting blocked?
Is your app a public or confidential one btw?
Also wondering @nvahnav if you think it can be somewhat related to the “Dev envionrments” tab, there is a statement saying:
To begin using one of our subscription APIs, you need to set up a dev environment for the endpoint. All of the subscription API packages support at least 1 dev environments (number is dependent on the details of your package), which can be used to isolate usage, rules, rate limits or otherwise within your systems. (Note: it may make the most sense to associate your business @username’s App).
Could this be related? It was previously disabled for me - i just enabled it. But from my understanding this is related to some webhooks functionality, not the example / basic use cases I am trying to support (fetch user bookmarks for example).
Will test out to confirm - but was just wondering if you ever updated something there?
Thanks!