401 unauthorized error while trying to load images in flutter app

I’ve been trying to add Sendbird with the help of Dashchat in a flutter app. So far, everything’s working fine except for the part where we have to load the images send by the user. It works fine in a webapp but in flutter mobile app, it keeps throwing 401 unauthorized error.
I’ve spend some time searching for a solution and found that we need a url with an authorization key to properly access any file messages. But in the response I’m getting from getMessagesByTimestamp, the url key does not contain the url with the authorization key. This is how the url ini my response looks like: https://file-us-1.sendbird.com/f5f8406ac8cb4565a5d80b2f470b16eb.png. In fact there’s another key require_auth is set to false. Then why am I not able to load these images. And yes, I did properly connect using the app id and access token before. Any help will be greatly appreciated.

Hi @Abin. Could you please add the part of the code which displays the file message and get the error in here?

@sardorbek.numonov .This is the code i use to display messages in dashchat.

                text: sbm.message,
                user: asDashChatUser(sbm.sender),
                createdAt: DateTime.fromMillisecondsSinceEpoch(sbm.createdAt),
               image: sbm.toJson()['url'],

These are the url keys and require_auth keys I get as a response when getting the messages

url: https://file-us-1.sendbird.com/f5f8406ac8cb4565a5d80b2f470b16eb.png
 require_auth: false

This is the error message I get when trying to load the images.

NetworkImageLoadException (HTTP request failed, statusCode: 401, https://file-us-1.sendbird.com/1898503bcb1844e8969080d41ac32a4c.png)

How do you send the file message to the channel? By Flutter SDK, or Platform API.
Actually, there is a “require_auth” parameter in FileMessage. It determines whether to attach or not auth=session_key to the main URL.

While sending FileMessage (as a file from local) to the channel in Flutter SDK, we set require_auth=true as default. Thus, we get URL (message.secureUrl) from FileMessage, which gives you a URL with auth=session_key

But, when you are sending FileMessage (as File URL), SDK may consider the URL can be external URL. So, SDK set require_auth=false.

So, when you load messages, FileMessage (as a file from local) will have auth=session_key, FileMessage (as a file From URL) will not have auth=session_key. Thus, you can’t access the file.

Can you use message.secureUrl instead of message.url?

Sendbird sdk along with dashchat has already been implemented when I started this project.

final sendMessage = _channel!.sendFileMessage(
          progress: (sentBytes, totalBytes) {
            print('$sentBytes / $totalBytes');
          onCompleted: (message, error) {
            // if (error == null) {
            print('send completed: ${message.message}');
            // } else {
            print('error message: ${error.toString()}');
            // }

This is how file messages are being send at the moment. Can you please specify where require_auth needs to be requested?

@sardorbek.numonov have you found anything?

Then, require_auth=true for your files. So, you need to use message.secureUrl. Did you try to use message.secureUrl? As I said before, it gives you a URL with auth=session_key

@sardorbek.numonov I’m sorry, could you be more specific, please? Where am I suppose to use message.secureUrl? While sending or downloading? and the require_auth parameter exists only within FileMessage as far as I know and not in FileMessageParams? But sendFileMessage needs the FileMessageParams object instead?

Also, another thing is, we have a website that uses the same sendbird database to store the files we send. And the files I send through the flutter mobile app without manually adjusting require_auth can be seen on the website. Even without the url that does not contain the auth key.

@sardorbek.numonov just FYI, we do not have a separate database to save the files we send as messages. That’s why we’re using the sendbird db to upload the files directly.

@Abin When you send FileMessage from SDK, Sendbird SDK will attach require_auth=true to the file message payload before uploading. We can turn off the file authentication via internal settings if you want. But your chat file message can be accessible as public. But, it is not recommended by Sendbird.

In Flutter SDK, it should be message.secureUrl in the FileMessage object. You can use the message.secureUrl to get file.url+?auth=session_key.

@sardorbek.numonov secureUrl did not give me the auth session key but I’ve tried the solution you’ve send me to get the key seperately:

final sdk = SendbirdSdk().getInternal();
final eKey = sdk.sessionManager.getEKey();
if (eKey != null) {
 image_url= '$url?auth=$eKey';

This has given me the key and I’ve managed to load the images. Thank you for your time and patience.

@Abin Great. But I wonder about the root cause of the issue. In the file message, the require_auth is false. So, message.secureUrl doesn’t attach auth to your file URL.

If you send a file message from SDK, the require_auth should be true. Can you check how the require_auth became false for your file message via testing more sending file messages from SDK?

After sending a message several times, can you let me know the channel URLs and APP ID via message if the require_auth is false and you still can’t open the file message without ?auth=session_key.

@sardorbek.numonov I have ran a few tests. The require_auth is set to true when the file message is send. I’ve checked that. But I still couldn’t figure out why it’s set to false when I get the list of messages. And as I mentioned earlier, message.secureUrl only gave me the url without the auth key. As for channel URLs and APP ID, I’m not sure how much I’m allowed to share by my company. I’ll ask the team leader and will message you if I get permission.

Hi @Abin. Yeah, you are right. Please create a support ticket for the Sendbird team for this case. I will handle the case there. Please put my name there too.