**Saya tidak menjelaskan cara membuat project di Firebase
Solusi
- Saya memiliki method
signInWithGoogle
seperti berikut:
dart
" ...\n \n Future<UserCredential?> signInWithGoogle() async {\n try {\n final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();\n \n if (googleUser == null) {\n return null;\n }\n\n final GoogleSignInAuthentication googleAuth = await googleUser.authentication;\n final OAuthCredential credential = GoogleAuthProvider.credential(\n accessToken: googleAuth.accessToken,\n idToken: googleAuth.idToken,\n );\n\n return await _auth.signInWithCredential(credential);\n } on FirebaseAuthException catch (e) {\n throw _handleAuthException(e);\n }\n }\n\n ..."
...
Future<UserCredential?> signInWithGoogle() async {
try {
final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
if (googleUser == null) {
return null;
}
final GoogleSignInAuthentication googleAuth = await googleUser.authentication;
final OAuthCredential credential = GoogleAuthProvider.credential(
accessToken: googleAuth.accessToken,
idToken: googleAuth.idToken,
);
return await _auth.signInWithCredential(credential);
} on FirebaseAuthException catch (e) {
throw _handleAuthException(e);
}
}
...
- Kemudian di event button login dengan Google:
dart
" ...\n \n onPressed: () async {\n final currentContext = context;\n\n final userCredential = await AuthService().signInWithGoogle();\n if (userCredential != null) {\n final user = userCredential.user;\n final idToken = await user!.getIdToken();\n\n // send user data to backend\n final response = await http.post(\n Uri.parse('${dotenv.env['API_URL']}/api/v1/auth/google-login'), // url backend\n headers: {'Content-Type': 'application/json'},\n body: json.encode({\n 'id_token': idToken,\n }),\n );\n\n if (currentContext.mounted) {\n if (response.statusCode == 200) {\n authService.setUserCredential(userCredential);\n // redirect to home\n Navigator.of(context).pushReplacementNamed('/home');\n } else {\n // show error message\n ScaffoldMessenger.of(context).showSnackBar(\n const SnackBar(\n content: Text('Login failed. Please try again.'),\n ),\n );\n }\n }\n }\n }\n ..."
...
onPressed: () async {
final currentContext = context;
final userCredential = await AuthService().signInWithGoogle();
if (userCredential != null) {
final user = userCredential.user;
final idToken = await user!.getIdToken();
// send user data to backend
final response = await http.post(
Uri.parse('${dotenv.env['API_URL']}/api/v1/auth/google-login'), // url backend
headers: {'Content-Type': 'application/json'},
body: json.encode({
'id_token': idToken,
}),
);
if (currentContext.mounted) {
if (response.statusCode == 200) {
authService.setUserCredential(userCredential);
// redirect to home
Navigator.of(context).pushReplacementNamed('/home');
} else {
// show error message
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Login failed. Please try again.'),
),
);
}
}
}
}
...
- Sedangkan di server Django saya, saya menggunakan library
google-auth
untuk memvalidasi token Firebase:
python
"from google.oauth2 import id_token\nfrom google.auth.transport import requests\nimport json\nimport random\nfrom .models import Akun\n\n...\n\ndef google_login(request):\n data = json.loads(request.body)\n token = data['id_token']\n\n try:\n # CLIENT_ID = 'xxxx.apps.googleusercontent.com'\n # idinfo = id_token.verify_oauth2_token(token, requests.Request(), CLIENT_ID)\n idinfo = id_token.verify_firebase_token(token, requests.Request())\n\n email = idinfo['email']\n username = idinfo['name']\n\n user, created = Akun.objects.get_or_create(\n email_akun=email,\n defaults={\n 'akun_id': random.randint(10**10, 10**11 - 1),\n 'username': username,\n 'masuk_dengan': 'GOOGLE',\n 'status_aktif': True\n }\n )"
from google.oauth2 import id_token
from google.auth.transport import requests
import json
import random
from .models import Akun
...
def google_login(request):
data = json.loads(request.body)
token = data['id_token']
try:
# CLIENT_ID = 'xxxx.apps.googleusercontent.com'
# idinfo = id_token.verify_oauth2_token(token, requests.Request(), CLIENT_ID)
idinfo = id_token.verify_firebase_token(token, requests.Request())
email = idinfo['email']
username = idinfo['name']
user, created = Akun.objects.get_or_create(
email_akun=email,
defaults={
'akun_id': random.randint(10**10, 10**11 - 1),
'username': username,
'masuk_dengan': 'GOOGLE',
'status_aktif': True
}
)
- bagian yang diberi komentar adalah kode yang saya dapatkan dari AI, tapi tidak bekerja. Cukup lama saya mencari solusi dan akhirnya saya menemukan solusi dari referensi. Saya mengganti
id_token.verify_oauth2_token
menjadiid_token.verify_firebase_token
dan berhasil. Jadi untuk token yang didapatkan dari Firebase, kita harus menggunakanverify_firebase_token
bukanverify_oauth2_token
.
Referensi
https://github.com/googleapis/google-auth-library-python/issues/316#issuecomment-667777124