Files
You can use Kinvey to store and retrieve binary files of size up to 5TB. Files can be of any format.
The files are automatically enabled for download using a Content Delivery Network (CDN) for massive scale and performance.
Kinvey does not directly serve or accept files. Instead, the Kinvey Files API works by providing a short-lived URL to a third-party cloud storage service from which file(s) can be uploaded or downloaded. Currently, the third-party service used is Google Cloud Storage.
You would typically use the Files API to upload and download:
- images
- video files
- other application-specific files.
When using the library, a file can be represented by:
- File, Blob, or ArrayBuffer object. This is the recommended way of representing a file.
- Simple value such as a string.
The library always communicates with Google Cloud Storage using the https
protocol. If you want to use http
instead, the options
argument in the methods described below allow for a tls: false
flag.
Download
To download a file given its _id
, use Kinvey.Files.download
. The response contains a string representation of the file content. If you only need to get the file metadata, use Files.find()
or consider streaming the file.
import { Component } from '@angular/core';
import { FilesService } from 'kinvey-angular-sdk';
@Component()
export class FilesComponent {
constructor(private filesService: FileService) { }
async download(id: string) {
try {
const file = await this.filesService.download(id);
console.log(file);
} catch (error) {
console.log(error);
}
}
}
Stream
For web applications, downloading the actual file is not a common use case. Often, just obtaining a download URL is sufficient. This holds for a variety of use cases, including:
- Prompt a file for download
- Embed an application-resource, such as a stylesheet
- Display an image
To stream a file, use stream()
. The response
will contain the file metadata, with the download URL available as _downloadURL
property.
import { Component } from '@angular/core';
import { FilesService } from 'kinvey-angular-sdk';
@Component()
export class FilesComponent {
constructor(private filesService: FileService) { }
async stream(id: string) {
try {
const file = await this.filesService.stream(id);
console.log(file);
} catch (error) {
console.log(error);
}
}
}
Query
To retrieve a list of files, the Querying interface is available for files.
The snippet below retrieves a list of all PNG images. The response is a list of file metadata.
import { Component } from '@angular/core';
import { FilesService, Query } from 'kinvey-angular-sdk';
@Component()
export class FilesComponent {
constructor(private filesService: FileService) { }
async find() {
try {
const query = new Query();
query.equalTo('mimeType', 'image/png');
const files = await this.filesService.find(query);
console.log(files);
} catch (error) {
console.log(error);
}
}
}
Optionally, you can add the download: true
flag to download every file found. The file itself will then become available under the _data
property of each file in the list.
download
flag. Every file matching the query will be downloaded regardless of its size, which can lead to significant overhead and performance degradation of your application.
The file metadata returned by any of the methods explained above contains a _downloadURL
. Depending on your use case, you might want to re-download a file. The Kinvey.Files.downloadByUrl()
method allows you to do just that. The method accepts a _downloadURL
.
import { Component } from '@angular/core';
import { FilesService } from 'kinvey-angular-sdk';
@Component()
export class FilesComponent {
constructor(private filesService: FileService) { }
async download(id: string) {
try {
const file = await this.filesService.download(id);
console.log(file);
} catch (error) {
console.log(error);
}
}
}
Specifying a custom expiration time
If you require the temporary download URL to last longer (or shorter) than the default of one hour, you may optionally specify a custom expiration time (in seconds) using the ttl
option. If the file is public, the returned download URL never expires.
import { Component } from '@angular/core';
import { FilesService } from 'kinvey-angular-sdk';
@Component()
export class FilesComponent {
constructor(private filesService: FileService) { }
async download(id: string) {
try {
const file = await this.filesService.download(id, { ttl: 7200 });
console.log(file);
} catch (error) {
console.log(error);
}
}
}
Upload
Use Kinvey.Files.upload()
to upload the file and, optionally, save any associated metadata along with it. The example below uploads a file represented as a string. The _id
and _filename
properties will be auto-generated by Kinvey if left out.
_id
, you should avoid values that are exactly 12 or 24 symbols in length. Such values are automatically converted to BSON ObjectID and are not stored as strings in the database, which can interfere with querying and other operations.
To ensure that no items with 12 or 24 symbols long _id
are stored in the collection, you can create a pre-save hook that either prevents saving such items, or appends an additional symbol (for example, underscore) to the _id
:
if (_id.length === 12 || _id.length === 24) {
_id += "_";
}
import { Component } from '@angular/core';
import { FilesService } from 'kinvey-angular-sdk';
@Component()
export class FilesComponent {
constructor(private filesService: FileService) { }
async upload() {
try {
const fileContent = '<file-content>';
const metadata ={
_id: '<file-id>',
filename: '<filename>',
mimeType: '<mime-type>',
size: fileContent.length
};
const file = await this.filesService.upload(fileContent, metadata);
console.log(file);
} catch (error) {
console.log(error);
}
}
}
Delete
To delete a file, use removeById()
.
import { Component } from '@angular/core';
import { FilesService } from 'kinvey-angular-sdk';
@Component()
export class FilesComponent {
constructor(private filesService: FileService) { }
async removeById(id: string) {
try {
const result = await this.filesService.removeById(id);
console.log(result);
} catch (error) {
console.log(error);
}
}
}
Linking files to entities in collections
Many common uses for files involve associating them with entities that reside in collections. In order to make this experience as easy as possible, entities in collections may contain KinveyFile references. These references will be automatically resolved when the entity that contains them is retrieved through the Data Store API.
Creating a KinveyFile reference
A reference to a file stored using Kinvey, or a KinveyFile reference, is simply a JSON object with a _type
of KinveyFile
and an _id
containing the ID of a file in Kinvey (as created through the File API).
To store a KinveyFile reference, create or update an entity in any collection with such a property. For example:
var dataStore = Kinvey.DataStore.collection('pets');
dataStore.save({
dogName: 'Bob',
furColor: 'brown with black spots',
pawPrintPicture: {
_type: 'KinveyFile',
_id: '325620e4-93dd-4a26-9f84-8a5e62c0db11'
}
})
.then(function(pet) {
// ...
})
.catch(function(error) {
// ...
});
Please note that only two properties are allowed in a KinveyFile reference: _type
and _id
. If you attempt to save any additional properties as part of the KinveyFile JSON object, these properties will be ignored by Kinvey and not saved. Any additional properties that you wish to assiciate with the file should be a part of the file itself, and set through the File API.
Downloading using a KinveyFile reference
When querying any collection through the Data Store API, Kinvey will resolve any KinveyFile reference and provide you with a _downloadURL
.
var dataStore = Kinvey.DataStore.collection('pets');
dataStore.findById('3f583e9f-d064-4a25-a953-6cf0a3dc2ff1')
.subscribe(function(pet) {
/*
{
"_id": "3f583e9f-d064-4a25-a953-6cf0a3dc2ff1",
"_acl": {...},
"dogName": "Bob",
"furColor": "brown with black spots",
"pawPrintPicture": {
"_type": "KinveyFile",
"_id": "325620e4-93dd-4a26-9f84-8a5e62c0db11",
"_filename": "bobsPawPrint.png",
"_acl": { ... },
"_downloadURL": <Google Cloud Storage download URL>,
"_expiresAt": "2018-06-18T23:07:23.394Z"
}
}
*/
}, function(error) {
// ...
});
You will then need to download the file directly from Google Cloud Storage by calling Kinvey.Files.downloadByUrl();
with the _downloadURL
property of the KinveyFiles reference.
_downloadURL
is a temporary URL that will expire one hour after your find()
or findById()
call is made to Kinvey. While you must begin your file download within that time limit, the download itself may take longer.
Specifying a custom expiration time using KinveyFiles
If you require the temporary download URL to last longer (or shorter) than one hour, you may optionally specify a custom expiration time (in seconds) using the kinveyFileTTL
query parameter.
var dataStore = Kinvey.DataStore.collection('pets');
dataStore.findById('3f583e9f-d064-4a25-a953-6cf0a3dc2ff1', { kinveyFileTTL: 3600 })
.subscribe(function(pet) {
/*
{
"_id": "3f583e9f-d064-4a25-a953-6cf0a3dc2ff1",
"_acl": {...},
"dogName": "Bob",
"furColor": "brown with black spots",
"pawPrintPicture": {
"_type": "KinveyFile",
"_id": "325620e4-93dd-4a26-9f84-8a5e62c0db11",
"_filename": "bobsPawPrint.png",
"_acl": { ... },
"_downloadURL": <Google Cloud Storage download URL>,
"_expiresAt": "2018-06-18T23:07:23.394Z"
}
}
*/
}, function(error) {
// ...
});
If you would like to upload a publicly-readable file that never expires, please refer to the upload publicly-readable files section.
Securely communicating with GCS using KinveyFiles
Secure communication is available as a query parameter when retrieving KinveyFile references through the Data Store API, as well. To use https
instead of http
, set the kinveyFileTLS
parameter to true
.
var dataStore = Kinvey.DataStore.collection('pets');
dataStore.findById('3f583e9f-d064-4a25-a953-6cf0a3dc2ff1', { kinveyFileTLS: true })
.subscribe(function(pet) {
/*
{
"_id": "3f583e9f-d064-4a25-a953-6cf0a3dc2ff1",
"_acl": {...},
"dogName": "Bob",
"furColor": "brown with black spots",
"pawPrintPicture": {
"_type": "KinveyFile",
"_id": "325620e4-93dd-4a26-9f84-8a5e62c0db11",
"_filename": "bobsPawPrint.png",
"_acl": { ... },
"_downloadURL": <Google Cloud Storage download URL>,
"_expiresAt": "2018-06-18T23:07:23.394Z"
}
}
*/
}, function(error) {
// ...
});
Business Logic
You may create Business Logic code which will execute before or after each File API v3 route. To do so, simply add hooks to the _blob collection just like any other data collection. For more information on Business Logic, refer to the Business Logic guide.
Comprehensive reference
Properties
While you may include any number of custom metadata properties when saving your file, Kinvey uses certain properties to maintain its own metadata. This section contains a comprehensive list of all special Kinvey attributes that may be part of a file.
Property | Short description |
---|---|
_id | A unique identifier |
_filename | A filename |
_acl | The file's Access Control List |
_kmd | Kinvey metadata, including lmt and ect |
_public | If set to true , the file is publicly accessible through an unsigned URL. Defaults to false |
_downloadURL | A link to GET the file |
_expiresAt | The time at which the link will expire. Will not be included if the file's _public attribute is set to true |
Special supported properties
The following properties, while optional, will allow the Kinvey Console to display more information about the file if you specify them as part of the file metadata.
Property | Short description |
---|---|
mimeType | The mime type of the file (e.g. text/plain, image/png, etc) |
Optional query parameters
Parameter | Applies to | Default | Short description |
---|---|---|---|
ttl | Downloading | 3600 | If set, Google Cloud Storage URLs will expire after the specified amount of time |
tls | Downloading and Uploading | false | If true, Google Cloud Storage URLs will use the https protocol instead of http |
kinveyFileTTL | KinveyFiles | 3600 | If set, Google Cloud Storage URLs will expire after the specified amount of time |
kinveyFileTLS | KinveyFiles | false | If true, Google Cloud Storage URLs will use the https protocol instead of http |