0

I'm getting this error when I try to upload an image.


"error": {
     "code": 401,
     "message": "Invalid Credentials",
     "errors": [
       {
         "message": "Invalid Credentials",
         "domain": "global",
         "reason": "authError",
         "locationType": "header",
         "location": "Authorization"
       }
     ]
   }
 }

I tried passing fileBytes to the data but it doesn't work. Firebase Storage doesn't work for flutter desktop that's why I'm using the rest api.


  Future<void> uploadProfilePicture({
    required String fileName,
    required String filePath,
    required String email,
  }) async {
    return Chain.capture(() async {
      final url =
          "https://storage.googleapis.com/upload/storage/v1/b/${Constants.projectID}.appspot.com/o?uploadType=media&name=$email/profilePicture/$fileName";

      // final fileBytes = await File(filePath).readAsBytes();

      final token = await FirebaseAuth.instance.tokenProvider.idToken;

      try {
        final response = await _dio.post<Map<String, dynamic>>(
          url,
          data: filePath,
          options: Options(
            headers: {
              "Content-Type": "image/jpeg",
              "Authorization": "Bearer $token,",
            },
          ),
        );

        logger.i(response.data);
      } on DioException catch (e, stackTrace) {
        final terseStacktrace = Chain.forTrace(stackTrace).terse;

        logger
          ..e("Failed to upload profile picture", [e, terseStacktrace])
          ..e("Error ${e.error} Message ${e.message} Response ${e.response}");
      } catch (e, stackTrace) {
        final terseStacktrace = Chain.forTrace(stackTrace).terse;

        logger.wtf("Failed to upload profile picture", [e, terseStacktrace]);

        rethrow;
      }
    });
  }

The above is based on this:


curl -X POST --data-binary @[OBJECT_LOCATION] \
-H "Authorization: Bearer [OAUTH2_TOKEN]" \
-H "Content-Type: [OBJECT_CONTENT_TYPE]" \
"https://storage.googleapis.com/upload/storage/v1/b/[BUCKET_NAME]/o?uploadType=media&name=[OBJECT_NAME]"

These are my Storage rules


service firebase.storage {
  match /b/{bucket}/o {
    allow read, write: if true
   }
}
Nana Kwame
  • 942
  • 1
  • 6
  • 21
  • 1
    Google Cloud Storage does not use identity tokens for authorization. Change this line of code to request an access token: `FirebaseAuth.instance.tokenProvider.idToken`. – John Hanley Aug 19 '23 at 18:26
  • Right, thanks a lot. Do you know of any guides for creating and using a service account on the client side? The official documentation is not clear to me – Nana Kwame Aug 19 '23 at 22:52
  • If you mean client side as in the public? Do not use service accounts client side as that is a big security risk. Google will consider that a leaked credential. If you mean at machines you control, there are lots of articles, blog posts, etc on creating credentials. – John Hanley Aug 19 '23 at 22:57
  • Good to know, thanks. – Nana Kwame Aug 20 '23 at 12:31

1 Answers1

0

Used cloud functions with a service account like here Uploading Files

Nana Kwame
  • 942
  • 1
  • 6
  • 21